Skip to content

Android certificates resent_certificate#49171

Merged
AndreyKizimenko merged 4 commits into
mainfrom
49007-android-activity
Jul 13, 2026
Merged

Android certificates resent_certificate#49171
AndreyKizimenko merged 4 commits into
mainfrom
49007-android-activity

Conversation

@ksykulev

@ksykulev ksykulev commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Related issue: Resolves #49007

Checklist for submitter

  • Added/updated automated tests
  • QA'd all new/changed functionality manually

For unreleased bug fixes in a release candidate, one of:

  • Confirmed that the fix is not expected to adversely impact load test results

Summary by CodeRabbit

  • New Features
    • SCIM user create/reactivation, replace, patch, and delete flows now automatically record certificate resend activities when applicable.
    • Certificate resend activities are generated alongside SCIM persistence, tied to the resulting “resent certificates”.
  • Bug Fixes
    • Improved reliability and synchronization of certificate resend activity recording during SCIM and Google Workspace reconciliation.
    • Failures to record individual resend activities no longer block the underlying SCIM operation.

@ksykulev ksykulev requested a review from a team as a code owner July 10, 2026 23:00
Copilot AI review requested due to automatic review settings July 10, 2026 23:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses #49007 by ensuring Fleet emits resent_certificate host activities when certificate templates are automatically resent due to SCIM-driven host variable changes (e.g., IdP attribute updates), aligning the auto-resend path with the manual resend behavior.

Changes:

  • Updated SCIM datastore methods to return the set of impacted certificate-template resend activities when variable-triggered resends occur.
  • Added logic in the SCIM user handlers to create resent_certificate activities (system actor) based on those returned details.
  • Adjusted call sites and tests to accommodate the updated datastore interface and validate returned activity details.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
server/service/integration_mdm_profiles_test.go Updated SCIM call signature usage in integration test.
server/service/integration_enterprise_test.go Updated SCIM deletion call signature usage in integration test defer cleanup.
server/mock/datastore_mock.go Updated mock datastore method signatures for SCIM user replace/delete.
server/fleet/datastore.go Updated Datastore interface for SCIM user replace/delete to return resent-certificate activity details.
server/datastore/mysql/scim.go Collects certificate-template resend activity details during variable-triggered resend operations and returns them to callers.
server/datastore/mysql/scim_test.go Adds assertions that ReplaceScimUser returns the expected resent-certificate activity details.
server/datastore/mysql/hosts.go Updated call site for triggerResendProfilesUsingVariables return signature.
server/cron/google_workspace_cron.go Updated cron SCIM replace/delete calls for new return signature.
server/cron/google_workspace_cron_test.go Updated cron test datastore mock functions for new return signature.
ee/server/scim/users.go Emits resent_certificate activities in SCIM handlers based on datastore-returned details.
ee/server/scim/users_test.go Updated SCIM handler tests’ mocks for new return signature.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread server/datastore/mysql/scim.go Outdated
Comment thread server/datastore/mysql/scim.go Outdated
Comment thread server/datastore/mysql/hosts.go Outdated
Comment thread ee/server/scim/users.go
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 24fb4f92-cdb7-4f01-a138-32486f400e46

📥 Commits

Reviewing files that changed from the base of the PR and between 7c531ba and 3f33fd9.

📒 Files selected for processing (1)
  • server/datastore/mysql/scim.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • server/datastore/mysql/scim.go

Walkthrough

SCIM datastore replacement and deletion now return certificates affected by automatic resend processing. SCIM user create reactivation, replace, delete, and patch handlers emit resent_certificate activities for those results after successful persistence. Interfaces, mocks, cron callers, integration helpers, and tests were updated for the new return signatures. Datastore tests also verify returned certificate activity details.

Possibly related PRs

  • fleetdm/fleet#48278: Extends the SCIM resend flow that this change uses to identify certificate templates affected by variable changes.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.25% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and clearly points to the Android certificate resent_certificate change.
Description check ✅ Passed The description includes the linked issue and key testing checklist items, with only non-critical template sections omitted.
Linked Issues check ✅ Passed The code now emits resent_certificate for SCIM-driven certificate resends, matching the Android auto-resend requirement in #49007.
Out of Scope Changes check ✅ Passed The cron and test updates support the SCIM signature change and do not appear unrelated to the requested fix.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 49007-android-activity

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
server/cron/google_workspace_cron.go (1)

180-222: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Emit resent_certificate activities from Google Workspace sync.
ReplaceScimUser and DeleteScimUser return resent-certificate details, but this cron drops them (if _, err := ...). That means directory-driven SCIM updates/deletes won’t create the resent_certificate activity trail that ee/server/scim/users.go records. Wire these results into the same activity-creation path here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/cron/google_workspace_cron.go` around lines 180 - 222, The Google
Workspace sync discards resent-certificate details from ReplaceScimUser and
DeleteScimUser, so required activities are not recorded. Capture the returned
resent-certificate data in the update and deletion branches of the sync
function, then pass it through the same activity-creation path used by SCIM user
operations, preserving existing error handling and counters.
server/datastore/mysql/scim.go (1)

1223-1277: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Propagate resent-certificate activities from SCIM group resends. triggerResendProfilesForIDPGroupChange* and triggerResendProfilesForIDPUserAddedToHost discard the []fleet.ActivityTypeResentCertificate returned by triggerResendProfilesUsingVariables, so these SCIM group/host-reassignment paths update profiles but never emit resent_certificate activities. Thread the slice back up to the datastore callers.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/datastore/mysql/scim.go` around lines 1223 - 1277, Update
triggerResendProfilesForIDPGroupChange,
triggerResendProfilesForIDPGroupChangeByUsers, and
triggerResendProfilesForIDPUserAddedToHost to return the
[]fleet.ActivityTypeResentCertificate from triggerResendProfilesUsingVariables
alongside any error, preserving it through early returns. Then update every
datastore caller to accept and propagate the returned activities so SCIM group
and host-reassignment profile resends emit resent_certificate activities.
🧹 Nitpick comments (1)
ee/server/scim/users_test.go (1)

381-386: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the new resend-activity emission path.

All updated mocks in this file return a nil certs slice, so no test verifies that u.newActivity is actually invoked with fleet.ActivityTypeResentCertificate when ReplaceScimUser/DeleteScimUser return non-empty results — the core behavior this PR introduces. Consider adding at least one case per handler (Create reactivation, Replace, Delete, Patch) where the mock returns a non-empty slice and the test asserts NewActivityFunc was called with the expected certificate.

Also applies to: 539-545, 700-703, 881-885, 1041-1048

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ee/server/scim/users_test.go` around lines 381 - 386, Add test coverage for
resend-activity emission in the Create reactivation, ReplaceScimUser,
DeleteScimUser, and Patch handler tests. Configure each relevant mock to return
a non-empty certificate slice, then assert NewActivityFunc is called with
fleet.ActivityTypeResentCertificate and the expected certificate data.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@server/cron/google_workspace_cron.go`:
- Around line 180-222: The Google Workspace sync discards resent-certificate
details from ReplaceScimUser and DeleteScimUser, so required activities are not
recorded. Capture the returned resent-certificate data in the update and
deletion branches of the sync function, then pass it through the same
activity-creation path used by SCIM user operations, preserving existing error
handling and counters.

In `@server/datastore/mysql/scim.go`:
- Around line 1223-1277: Update triggerResendProfilesForIDPGroupChange,
triggerResendProfilesForIDPGroupChangeByUsers, and
triggerResendProfilesForIDPUserAddedToHost to return the
[]fleet.ActivityTypeResentCertificate from triggerResendProfilesUsingVariables
alongside any error, preserving it through early returns. Then update every
datastore caller to accept and propagate the returned activities so SCIM group
and host-reassignment profile resends emit resent_certificate activities.

---

Nitpick comments:
In `@ee/server/scim/users_test.go`:
- Around line 381-386: Add test coverage for resend-activity emission in the
Create reactivation, ReplaceScimUser, DeleteScimUser, and Patch handler tests.
Configure each relevant mock to return a non-empty certificate slice, then
assert NewActivityFunc is called with fleet.ActivityTypeResentCertificate and
the expected certificate data.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 52f10783-f6bd-4b14-ae6b-19aa6890b05d

📥 Commits

Reviewing files that changed from the base of the PR and between c5575e9 and 71f6a2f.

📒 Files selected for processing (11)
  • ee/server/scim/users.go
  • ee/server/scim/users_test.go
  • server/cron/google_workspace_cron.go
  • server/cron/google_workspace_cron_test.go
  • server/datastore/mysql/hosts.go
  • server/datastore/mysql/scim.go
  • server/datastore/mysql/scim_test.go
  • server/fleet/datastore.go
  • server/mock/datastore_mock.go
  • server/service/integration_enterprise_test.go
  • server/service/integration_mdm_profiles_test.go

@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 76.15385% with 31 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.99%. Comparing base (6430e61) to head (3f33fd9).
⚠️ Report is 29 commits behind head on main.

Files with missing lines Patch % Lines
server/datastore/mysql/scim.go 84.82% 10 Missing and 7 partials ⚠️
ee/server/scim/users.go 25.00% 8 Missing and 4 partials ⚠️
server/cron/google_workspace_cron.go 0.00% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #49171      +/-   ##
==========================================
+ Coverage   67.95%   67.99%   +0.04%     
==========================================
  Files        3766     3768       +2     
  Lines      238601   239175     +574     
  Branches    12579    12579              
==========================================
+ Hits       162132   162633     +501     
+ Misses      61817    61765      -52     
- Partials    14652    14777     +125     
Flag Coverage Δ
backend 69.56% <76.15%> (+0.05%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@juan-fdz-hawa juan-fdz-hawa self-assigned this Jul 13, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
server/datastore/mysql/scim.go (1)

265-277: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Keep collected certificates local to each transaction attempt.

Appending to an outer resentCerts slice inside a retried transaction can retain certificates from rolled-back attempts, producing duplicate or stale audit activities. Build an attempt-local slice and replace the returned result only at the end of each successful callback attempt.

Also applies to: 361-373, 410-444

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/datastore/mysql/scim.go` around lines 265 - 277, Update the retry
callback in the user email update flow around withRetryTxx so resent
certificates are accumulated in an attempt-local slice rather than the outer
resentCerts variable. Assign the local slice to resentCerts only after the
transaction callback completes successfully, and apply the same isolation to the
corresponding retry blocks around the references at lines 361-373 and 410-444.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/datastore/mysql/scim.go`:
- Around line 1252-1253: Update triggerResendProfilesUsingVariables and its
variable-triggered callers to return the affected certificate payloads instead
of discarding them. Apply this to all resend paths for
FleetVarHostEndUserIDPGroups and the other variables handled by the nearby
wrappers, then propagate those payloads so each automatic resend emits both the
resend activity and resent_certificate.

---

Outside diff comments:
In `@server/datastore/mysql/scim.go`:
- Around line 265-277: Update the retry callback in the user email update flow
around withRetryTxx so resent certificates are accumulated in an attempt-local
slice rather than the outer resentCerts variable. Assign the local slice to
resentCerts only after the transaction callback completes successfully, and
apply the same isolation to the corresponding retry blocks around the references
at lines 361-373 and 410-444.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ec13eac4-1ce8-4e93-92b5-b4a816b7b7c0

📥 Commits

Reviewing files that changed from the base of the PR and between cc40a31 and 7c531ba.

📒 Files selected for processing (1)
  • server/datastore/mysql/scim.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
server/datastore/mysql/scim.go (1)

265-277: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Keep collected certificates local to each transaction attempt.

Appending to an outer resentCerts slice inside a retried transaction can retain certificates from rolled-back attempts, producing duplicate or stale audit activities. Build an attempt-local slice and replace the returned result only at the end of each successful callback attempt.

Also applies to: 361-373, 410-444

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/datastore/mysql/scim.go` around lines 265 - 277, Update the retry
callback in the user email update flow around withRetryTxx so resent
certificates are accumulated in an attempt-local slice rather than the outer
resentCerts variable. Assign the local slice to resentCerts only after the
transaction callback completes successfully, and apply the same isolation to the
corresponding retry blocks around the references at lines 361-373 and 410-444.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/datastore/mysql/scim.go`:
- Around line 1252-1253: Update triggerResendProfilesUsingVariables and its
variable-triggered callers to return the affected certificate payloads instead
of discarding them. Apply this to all resend paths for
FleetVarHostEndUserIDPGroups and the other variables handled by the nearby
wrappers, then propagate those payloads so each automatic resend emits both the
resend activity and resent_certificate.

---

Outside diff comments:
In `@server/datastore/mysql/scim.go`:
- Around line 265-277: Update the retry callback in the user email update flow
around withRetryTxx so resent certificates are accumulated in an attempt-local
slice rather than the outer resentCerts variable. Assign the local slice to
resentCerts only after the transaction callback completes successfully, and
apply the same isolation to the corresponding retry blocks around the references
at lines 361-373 and 410-444.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ec13eac4-1ce8-4e93-92b5-b4a816b7b7c0

📥 Commits

Reviewing files that changed from the base of the PR and between cc40a31 and 7c531ba.

📒 Files selected for processing (1)
  • server/datastore/mysql/scim.go
🛑 Comments failed to post (1)
server/datastore/mysql/scim.go (1)

1252-1253: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Propagate resend activities from every variable-triggered certificate resend path.

Lines 1252, 1265, and 1280 can resend certificate templates but discard the affected certificates. Consequently, group changes and host-user association changes still cannot emit resent_certificate, contrary to the requirement that automatic resends produce both activity types. Extend these wrappers and their callers to return the certificate payloads.

Also applies to: 1265-1266, 1280-1287

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/datastore/mysql/scim.go` around lines 1252 - 1253, Update
triggerResendProfilesUsingVariables and its variable-triggered callers to return
the affected certificate payloads instead of discarding them. Apply this to all
resend paths for FleetVarHostEndUserIDPGroups and the other variables handled by
the nearby wrappers, then propagate those payloads so each automatic resend
emits both the resend activity and resent_certificate.

@juan-fdz-hawa

Copy link
Copy Markdown
Contributor

LGTM - only thing that need addressing are those failing tests

cdcme
cdcme previously approved these changes Jul 13, 2026

@cdcme cdcme left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving pending test fixes.

@AndreyKizimenko AndreyKizimenko merged commit 3b329e4 into main Jul 13, 2026
45 checks passed
@AndreyKizimenko AndreyKizimenko deleted the 49007-android-activity branch July 13, 2026 18:22
ksykulev added a commit that referenced this pull request Jul 13, 2026
Original issue: #49007
Original PR: [#49171](#49171)

# Checklist for submitter

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Android certificates: automatic (variable-triggered) resend records installed_certificate but not resent_certificate activity

5 participants