Commit Graph

4 Commits

Author SHA1 Message Date
Alphaeus Mote 5920b690d1 feat(rules): dynamic-group reconciliation + editor-facing APIs
Turns rules into Adaxes/Active-Roles style dynamic groups. The core new
capability is a set-level SyncGroupMembership action that reconciles a
target group's membership against the matched object set in one pass
instead of the old add-only, per-object behaviour.

Engine / reconciliation:
- New ActionSyncGroupMembership runs once per target group after the
  match: resolve (and optionally create) the group, read its current
  members, diff against the matched set, and apply the adds/removes.
- Three per-rule sync modes (types.SyncMode): FullSync (membership ==
  matched set; removes stale members incl. manual adds), ManagedAdd (adds
  matches, removes only members this rule added), AddOnly (never removes).
- Managed ownership tracked in a new managed_group_members table
  (migration 005) + repository, wired into the runner's engine so
  ManagedAdd removes only what it added.
- Adds/removes are recorded as AddToGroup / RemoveFromGroupIfNoLongerMatched
  run-actions so the activity feed categorises them as syncs/removals.
- Preview now computes an accurate, non-mutating diff for sync actions
  (+add / -remove / already-in-sync counts and per-member entries).
- memberOf and memberOf-recursive (LDAP_MATCHING_RULE_IN_CHAIN) operators;
  Regex no longer silently degrades to equals.
- Canonical group targets: CanonicalToLeafDN / NormalizeGroupTarget so a
  target group can be given as domain.com/OU/Group as well as a DN.

Editor-facing APIs (backend-first; UI comes next):
- Rule create/update now accept conditionGroups + actions and persist them
  via RuleRepository.ReplaceLogic (soft-delete + insert, preserving the
  rule_run_actions FK). Omitting them leaves existing logic untouched.
- POST /api/v1/rules/preview evaluates an unsaved draft (live match panel).
- GET /api/v1/rules/metadata serves the operator vocabulary (object types,
  operators, action types, sync modes, common attributes) so UI dropdowns
  stay in lock-step with the backend.
- GET /api/v1/ad-connections/{id}/directory searches groups/OUs for the
  target pickers.

Tests: reconciliation across all three modes + create-if-missing and the
missing-group error path (fake directory client); canonical leaf-DN
conversion; ReplaceLogic round-trip. Full suite green.

Note: RuleRepository.GetByID nests a query (getConditionGroups holds a
cursor while calling getConditions); safe under the production pool (25)
but a follow-up should flatten it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-02 14:57:30 -04:00
Alphaeus Mote c840ed054c feat(rules): expose operator-friendly canonical names for matched objects
Add ldap.CanonicalName: prefer the directory's canonicalName attribute (now
requested in searches) and otherwise build domain.com/OU/OU/CN from the DN.
Populate MatchedObject.CanonicalName and return it in the rule preview API so
operators see canonical names instead of raw DNs. Unit-tested.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-02 12:43:09 -04:00
GraceSolutions bca862ca01 feat(rules): implement end-to-end rule execution pipeline
- Add engine.Execute() that searches AD, iterates matches, runs actions,
  honors StopOnError and PreviewOnly, and supports context cancellation
- Resolve base DN and search scope from rule override then connection defaults
- Add actionExecutor covering AddToGroup, AddGroupToGroup, EnsureGroupExists,
  MoveToOu, and RemoveFromGroupIfNoLongerMatched with dynamic DN expansion
- Add RuleRunRepository persisting rule_runs and rule_run_actions
- Add Runner coordinator that loads rule+connection, builds an LDAP client,
  invokes the engine, and records the run + per-action outcomes
- Expose ConnectionService.BuildClient / BuildLDAPConfig for reuse
- Scheduler now accepts a RuleRunner and invokes it when a scheduled rule fires
2026-04-23 12:12:59 -04:00
GraceSolutions 060094ce7a feat: Add rule engine, services, and business logic
- Rule engine with preview and condition evaluation
- LDAP filter generation from rule conditions
- Connection service with full test workflow
- Credential service with encryption/decryption
- Rule service with validation
- Backup service with retention management
- Integration between services and repositories
2026-04-19 10:13:29 -04:00