Initial import — snapshot from admin host /srv/gosec/gsc-ops-api
This repo had no version control prior to this commit. The import is a
straight snapshot of the working tree at 2026-05-03; the deployed
binary on fihelvop01 was being rebuilt from this source via `make
build` + scp into place, with no upstream review path.
The snapshot already includes one in-flight fix made on 2026-05-03 to
internal/service/persona.go:GetSelfModel — the handler queried
`source` and `strength` columns plus an `is_active = true` filter on
persona.persona_commitments, none of which exist on that table (its
shape is session-bound commitments with `status`, `commitment_meta`,
etc.). The query returned a 500 every time SynapseHub bootstrapped a
persona's self-model, dropping the IdentityConstraints / Commitments /
ConscienceStandards layer from the assembled prompt. The patched
query reads existing columns only (commitment_text, commitment_type),
filters on `status='active'`, and synthesises Source="learned" /
Strength=1.0 to keep the SelfModel response shape stable for callers.
Verified live: `GET /api/v1/personas/70f7cfd9-.../self-model` now
returns 200 with `{identityConstraints:[],commitments:[],
conscienceStandards:[]}` instead of 500.
Future changes go through PRs against this repo — no more bin-only
deploys.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
341
internal/schema/attributes.go
Normal file
341
internal/schema/attributes.go
Normal file
@@ -0,0 +1,341 @@
|
||||
package schema
|
||||
|
||||
// registerAttributes registers all 292 GoSec LDAP attribute definitions
|
||||
// organized by OID branch/domain.
|
||||
func (r *Registry) registerAttributes() {
|
||||
// ── common (7) ──────────────────────────────────────────────────
|
||||
r.addAttr("gscCreatedAt", "createdAt", AttrTime, "common", true)
|
||||
r.addAttr("gscModifiedAt", "modifiedAt", AttrTime, "common", true)
|
||||
r.addAttr("gscCreatedBy", "createdBy", AttrDN, "common", true)
|
||||
r.addAttr("gscModifiedBy", "modifiedBy", AttrDN, "common", true)
|
||||
r.addAttr("gscDescription", "description", AttrString, "common", false)
|
||||
r.addAttr("gscEnabled", "enabled", AttrBool, "common", false)
|
||||
r.addAttr("gscNotes", "notes", AttrString, "common", false)
|
||||
|
||||
// ── tenant (10) ─────────────────────────────────────────────────
|
||||
r.addAttr("gscTenantId", "tenantId", AttrString, "tenant", false)
|
||||
r.addAttr("gscTenantName", "tenantName", AttrString, "tenant", false)
|
||||
r.addAttr("gscTenantDomain", "tenantDomain", AttrString, "tenant", false)
|
||||
r.addAttr("gscTenantStatus", "tenantStatus", AttrString, "tenant", false)
|
||||
r.addAttr("gscTenantQuota", "tenantQuota", AttrInt, "tenant", false)
|
||||
r.addAttr("gscTenantMaxUsers", "tenantMaxUsers", AttrInt, "tenant", false)
|
||||
r.addAttr("gscTenantCreatedAt", "tenantCreatedAt", AttrTime, "tenant", true)
|
||||
r.addAttr("gscTenantServices", "tenantServices", AttrStringMulti, "tenant", false)
|
||||
r.addAttr("gscTenantAdminDN", "tenantAdminDN", AttrDN, "tenant", false)
|
||||
r.addAttr("gscTenantParentDN", "tenantParentDN", AttrDN, "tenant", false)
|
||||
|
||||
// ── hash (5) ────────────────────────────────────────────────────
|
||||
r.addAttr("gscUserTenantHash", "tenantHash", AttrString, "hash", true)
|
||||
r.addAttr("gscUserTenantHashSalt", "tenantHashSalt", AttrString, "hash", true)
|
||||
r.addAttr("gscUserTenantHashVersion", "tenantHashVersion", AttrInt, "hash", true)
|
||||
r.addAttr("gscUserTenantHashCreatedAt", "tenantHashCreatedAt", AttrTime, "hash", true)
|
||||
r.addAttr("gscUserTenantHashVerifiedAt", "tenantHashVerifiedAt", AttrTime, "hash", true)
|
||||
|
||||
// ── customer (7) ────────────────────────────────────────────────
|
||||
r.addAttr("gscCustomerId", "customerId", AttrString, "customer", false)
|
||||
r.addAttr("gscSID", "sid", AttrString, "customer", false)
|
||||
r.addAttr("gscSIDCustomerPart", "sidCustomerPart", AttrString, "customer", false)
|
||||
r.addAttr("gscSIDTenantPart", "sidTenantPart", AttrString, "customer", false)
|
||||
r.addAttr("gscSIDSpecial1", "sidSpecial1", AttrString, "customer", false)
|
||||
r.addAttr("gscSIDSpecial2", "sidSpecial2", AttrString, "customer", false)
|
||||
r.addAttr("gscSIDUserPart", "sidUserPart", AttrString, "customer", false)
|
||||
|
||||
// ── mail (8) ────────────────────────────────────────────────────
|
||||
r.addAttr("gscMailEnabled", "enabled", AttrBool, "mail", false)
|
||||
r.addAttr("gscMailQuota", "quota", AttrInt, "mail", false)
|
||||
r.addAttr("gscMailAlias", "alias", AttrStringMulti, "mail", false)
|
||||
r.addAttr("gscMailForward", "forward", AttrString, "mail", false)
|
||||
r.addAttr("gscMailAutoReply", "autoReply", AttrBool, "mail", false)
|
||||
r.addAttr("gscMailAutoReplyMessage", "autoReplyMessage", AttrString, "mail", false)
|
||||
r.addAttr("gscMailTransport", "transport", AttrString, "mail", false)
|
||||
r.addAttr("gscMailDomain", "domain", AttrString, "mail", false)
|
||||
|
||||
// ── conf (5) ────────────────────────────────────────────────────
|
||||
r.addAttr("gscConfEnabled", "enabled", AttrBool, "conf", false)
|
||||
r.addAttr("gscConfRole", "role", AttrString, "conf", false)
|
||||
r.addAttr("gscConfMaxParticipants", "maxParticipants", AttrInt, "conf", false)
|
||||
r.addAttr("gscConfRecordingEnabled", "recordingEnabled", AttrBool, "conf", false)
|
||||
r.addAttr("gscConfDefaultRoom", "defaultRoom", AttrString, "conf", false)
|
||||
|
||||
// ── ftp (6) ─────────────────────────────────────────────────────
|
||||
r.addAttr("gscFtpEnabled", "enabled", AttrBool, "ftp", false)
|
||||
r.addAttr("gscFtpQuota", "quota", AttrInt, "ftp", false)
|
||||
r.addAttr("gscFtpHomeDir", "homeDir", AttrString, "ftp", false)
|
||||
r.addAttr("gscFtpUploadBandwidth", "uploadBandwidth", AttrInt, "ftp", false)
|
||||
r.addAttr("gscFtpDownloadBandwidth", "downloadBandwidth", AttrInt, "ftp", false)
|
||||
r.addAttr("gscFtpAllowedIPs", "allowedIPs", AttrStringMulti, "ftp", false)
|
||||
|
||||
// ── file (5) ────────────────────────────────────────────────────
|
||||
r.addAttr("gscFileEnabled", "enabled", AttrBool, "file", false)
|
||||
r.addAttr("gscFileQuota", "quota", AttrInt, "file", false)
|
||||
r.addAttr("gscFileHomeDir", "homeDir", AttrString, "file", false)
|
||||
r.addAttr("gscFileVersioning", "versioning", AttrBool, "file", false)
|
||||
r.addAttr("gscFileMaxFileSize", "maxFileSize", AttrInt, "file", false)
|
||||
|
||||
// ── sharing (5) ────────────────────────────────────────────────
|
||||
r.addAttr("gscShareEnabled", "enabled", AttrBool, "sharing", false)
|
||||
r.addAttr("gscShareExternalEnabled", "externalEnabled", AttrBool, "sharing", false)
|
||||
r.addAttr("gscShareMaxRecipients", "maxRecipients", AttrInt, "sharing", false)
|
||||
r.addAttr("gscShareDefaultExpiry", "defaultExpiry", AttrInt, "sharing", false)
|
||||
r.addAttr("gscSharePasswordRequired", "passwordRequired", AttrBool, "sharing", false)
|
||||
|
||||
// ── calendar (5) ───────────────────────────────────────────────
|
||||
r.addAttr("gscCalEnabled", "enabled", AttrBool, "calendar", false)
|
||||
r.addAttr("gscCalDefaultCalendar", "defaultCalendar", AttrString, "calendar", false)
|
||||
r.addAttr("gscCalTimezone", "timezone", AttrString, "calendar", false)
|
||||
r.addAttr("gscCalFreeBusyPublic", "freeBusyPublic", AttrBool, "calendar", false)
|
||||
r.addAttr("gscCalDelegates", "delegates", AttrDNMulti, "calendar", false)
|
||||
|
||||
// ── telephony (8) ──────────────────────────────────────────────
|
||||
r.addAttr("gscTelEnabled", "enabled", AttrBool, "telephony", false)
|
||||
r.addAttr("gscTelExtension", "extension", AttrString, "telephony", false)
|
||||
r.addAttr("gscTelDID", "did", AttrString, "telephony", false)
|
||||
r.addAttr("gscTelVoicemailEnabled", "voicemailEnabled", AttrBool, "telephony", false)
|
||||
r.addAttr("gscTelVoicemailPin", "voicemailPin", AttrString, "telephony", false)
|
||||
r.addAttr("gscTelCallForward", "callForward", AttrString, "telephony", false)
|
||||
r.addAttr("gscTelCallGroup", "callGroup", AttrString, "telephony", false)
|
||||
r.addAttr("gscTelRecordCalls", "recordCalls", AttrBool, "telephony", false)
|
||||
|
||||
// ── contacts (4) ──────────────────────────────────────────────
|
||||
r.addAttr("gscContactsEnabled", "enabled", AttrBool, "contacts", false)
|
||||
r.addAttr("gscContactsShared", "shared", AttrBool, "contacts", false)
|
||||
r.addAttr("gscContactsMaxContacts", "maxContacts", AttrInt, "contacts", false)
|
||||
r.addAttr("gscContactsExportEnabled", "exportEnabled", AttrBool, "contacts", false)
|
||||
|
||||
// ── ai (5) ─────────────────────────────────────────────────────
|
||||
r.addAttr("gscAIEnabled", "enabled", AttrBool, "ai", false)
|
||||
r.addAttr("gscAIModel", "model", AttrString, "ai", false)
|
||||
r.addAttr("gscAIMaxTokens", "maxTokens", AttrInt, "ai", false)
|
||||
r.addAttr("gscAIFeatures", "features", AttrStringMulti, "ai", false)
|
||||
r.addAttr("gscAIUsageQuota", "usageQuota", AttrInt, "ai", false)
|
||||
|
||||
// ── resource (9) ──────────────────────────────────────────────
|
||||
r.addAttr("gscResourceId", "resourceId", AttrString, "resource", false)
|
||||
r.addAttr("gscResourceName", "resourceName", AttrString, "resource", false)
|
||||
r.addAttr("gscResourceType", "resourceType", AttrString, "resource", false)
|
||||
r.addAttr("gscResourceEmail", "resourceEmail", AttrString, "resource", false)
|
||||
r.addAttr("gscResourceCapacity", "capacity", AttrInt, "resource", false)
|
||||
r.addAttr("gscResourceLocation", "location", AttrString, "resource", false)
|
||||
r.addAttr("gscResourceBookable", "bookable", AttrBool, "resource", false)
|
||||
r.addAttr("gscResourceApprovalRequired", "approvalRequired", AttrBool, "resource", false)
|
||||
r.addAttr("gscResourceOwnerDN", "ownerDN", AttrDN, "resource", false)
|
||||
|
||||
// ── dlp (10) ──────────────────────────────────────────────────
|
||||
r.addAttr("gscDlpEnabled", "enabled", AttrBool, "dlp", false)
|
||||
r.addAttr("gscDlpPolicyDN", "policyDN", AttrDNMulti, "dlp", false)
|
||||
r.addAttr("gscDlpExempt", "exempt", AttrBool, "dlp", false)
|
||||
r.addAttr("gscDlpPolicyName", "policyName", AttrString, "dlp", false)
|
||||
r.addAttr("gscDlpPolicyType", "policyType", AttrString, "dlp", false)
|
||||
r.addAttr("gscDlpPolicyRules", "policyRules", AttrStringMulti, "dlp", false)
|
||||
r.addAttr("gscDlpPolicyAction", "policyAction", AttrString, "dlp", false)
|
||||
r.addAttr("gscDlpPolicyPriority", "policyPriority", AttrInt, "dlp", false)
|
||||
r.addAttr("gscDlpPolicyScope", "policyScope", AttrStringMulti, "dlp", false)
|
||||
r.addAttr("gscDlpPolicyStatus", "policyStatus", AttrString, "dlp", false)
|
||||
|
||||
// ── sensitivity (9) ──────────────────────────────────────────
|
||||
r.addAttr("gscSensitivityEnabled", "enabled", AttrBool, "sensitivity", false)
|
||||
r.addAttr("gscSensitivityDefaultLabel", "defaultLabel", AttrString, "sensitivity", false)
|
||||
r.addAttr("gscSensitivityLabelName", "labelName", AttrString, "sensitivity", false)
|
||||
r.addAttr("gscSensitivityLabelPriority", "labelPriority", AttrInt, "sensitivity", false)
|
||||
r.addAttr("gscSensitivityLabelColor", "labelColor", AttrString, "sensitivity", false)
|
||||
r.addAttr("gscSensitivityLabelTooltip", "labelTooltip", AttrString, "sensitivity", false)
|
||||
r.addAttr("gscSensitivityLabelScope", "labelScope", AttrStringMulti, "sensitivity", false)
|
||||
r.addAttr("gscSensitivityEncryptionRequired", "encryptionRequired", AttrBool, "sensitivity", false)
|
||||
r.addAttr("gscSensitivityWatermark", "watermark", AttrBool, "sensitivity", false)
|
||||
|
||||
// ── encryption (8) ──────────────────────────────────────────
|
||||
r.addAttr("gscEncryptionEnabled", "enabled", AttrBool, "encryption", false)
|
||||
r.addAttr("gscEncryptionKeyDN", "keyDN", AttrDN, "encryption", false)
|
||||
r.addAttr("gscEncryptionPolicyName", "policyName", AttrString, "encryption", false)
|
||||
r.addAttr("gscEncryptionPolicyType", "policyType", AttrString, "encryption", false)
|
||||
r.addAttr("gscEncryptionAlgorithm", "algorithm", AttrString, "encryption", false)
|
||||
r.addAttr("gscEncryptionKeyLength", "keyLength", AttrInt, "encryption", false)
|
||||
r.addAttr("gscEncryptionScope", "scope", AttrStringMulti, "encryption", false)
|
||||
r.addAttr("gscEncryptionPolicyStatus", "policyStatus", AttrString, "encryption", false)
|
||||
|
||||
// ── retention (10) ──────────────────────────────────────────
|
||||
r.addAttr("gscRetentionEnabled", "enabled", AttrBool, "retention", false)
|
||||
r.addAttr("gscRetentionPolicyDN", "policyDN", AttrDNMulti, "retention", false)
|
||||
r.addAttr("gscRetentionPolicyName", "policyName", AttrString, "retention", false)
|
||||
r.addAttr("gscRetentionPolicyType", "policyType", AttrString, "retention", false)
|
||||
r.addAttr("gscRetentionDuration", "duration", AttrInt, "retention", false)
|
||||
r.addAttr("gscRetentionAction", "action", AttrString, "retention", false)
|
||||
r.addAttr("gscRetentionScope", "scope", AttrStringMulti, "retention", false)
|
||||
r.addAttr("gscRetentionPolicyStatus", "policyStatus", AttrString, "retention", false)
|
||||
r.addAttr("gscRetentionExcludeFolders", "excludeFolders", AttrStringMulti, "retention", false)
|
||||
r.addAttr("gscRetentionLegalHold", "legalHold", AttrBool, "retention", false)
|
||||
|
||||
// ── ediscovery (11) ─────────────────────────────────────────
|
||||
r.addAttr("gscEDiscoveryEnabled", "enabled", AttrBool, "ediscovery", false)
|
||||
r.addAttr("gscEDiscoveryCustodian", "custodian", AttrBool, "ediscovery", false)
|
||||
r.addAttr("gscEDiscoveryCaseName", "caseName", AttrString, "ediscovery", false)
|
||||
r.addAttr("gscEDiscoveryCaseStatus", "caseStatus", AttrString, "ediscovery", false)
|
||||
r.addAttr("gscEDiscoveryCaseCreatedAt", "caseCreatedAt", AttrTime, "ediscovery", false)
|
||||
r.addAttr("gscEDiscoveryCaseClosedAt", "caseClosedAt", AttrTime, "ediscovery", false)
|
||||
r.addAttr("gscEDiscoveryHoldName", "holdName", AttrString, "ediscovery", false)
|
||||
r.addAttr("gscEDiscoveryHoldScope", "holdScope", AttrStringMulti, "ediscovery", false)
|
||||
r.addAttr("gscEDiscoveryHoldStatus", "holdStatus", AttrString, "ediscovery", false)
|
||||
r.addAttr("gscEDiscoveryHoldCreatedAt", "holdCreatedAt", AttrTime, "ediscovery", false)
|
||||
r.addAttr("gscEDiscoverySearchQuery", "searchQuery", AttrString, "ediscovery", false)
|
||||
|
||||
// ── audit (9) ───────────────────────────────────────────────
|
||||
r.addAttr("gscAuditEnabled", "enabled", AttrBool, "audit", false)
|
||||
r.addAttr("gscAuditLevel", "level", AttrString, "audit", false)
|
||||
r.addAttr("gscAuditPolicyName", "policyName", AttrString, "audit", false)
|
||||
r.addAttr("gscAuditPolicyScope", "policyScope", AttrStringMulti, "audit", false)
|
||||
r.addAttr("gscAuditPolicyActions", "policyActions", AttrStringMulti, "audit", false)
|
||||
r.addAttr("gscAuditPolicyStatus", "policyStatus", AttrString, "audit", false)
|
||||
r.addAttr("gscAuditRetentionDays", "retentionDays", AttrInt, "audit", false)
|
||||
r.addAttr("gscAuditAlertEnabled", "alertEnabled", AttrBool, "audit", false)
|
||||
r.addAttr("gscAuditAlertRecipients", "alertRecipients", AttrStringMulti, "audit", false)
|
||||
|
||||
// ── iam (12) ────────────────────────────────────────────────
|
||||
r.addAttr("gscIAMEnabled", "enabled", AttrBool, "iam", false)
|
||||
r.addAttr("gscIAMMFARequired", "mfaRequired", AttrBool, "iam", false)
|
||||
r.addAttr("gscIAMMFAMethod", "mfaMethod", AttrString, "iam", false)
|
||||
r.addAttr("gscIAMPasswordPolicy", "passwordPolicy", AttrString, "iam", false)
|
||||
r.addAttr("gscIAMSessionTimeout", "sessionTimeout", AttrInt, "iam", false)
|
||||
r.addAttr("gscIAMMaxSessions", "maxSessions", AttrInt, "iam", false)
|
||||
r.addAttr("gscIAMIPRestrictions", "ipRestrictions", AttrStringMulti, "iam", false)
|
||||
r.addAttr("gscIAMRiskLevel", "riskLevel", AttrString, "iam", false)
|
||||
r.addAttr("gscIAMCAPolicyName", "caPolicyName", AttrString, "iam", false)
|
||||
r.addAttr("gscIAMCAPolicyConditions", "caPolicyConditions", AttrStringMulti, "iam", false)
|
||||
r.addAttr("gscIAMCAPolicyActions", "caPolicyActions", AttrStringMulti, "iam", false)
|
||||
r.addAttr("gscIAMCAPolicyStatus", "caPolicyStatus", AttrString, "iam", false)
|
||||
|
||||
// ── collaboration (10) ──────────────────────────────────────
|
||||
r.addAttr("gscCollabEnabled", "enabled", AttrBool, "collaboration", false)
|
||||
r.addAttr("gscCollabTeamsEnabled", "teamsEnabled", AttrBool, "collaboration", false)
|
||||
r.addAttr("gscCollabChannelsEnabled", "channelsEnabled", AttrBool, "collaboration", false)
|
||||
r.addAttr("gscCollabExternalEnabled", "externalEnabled", AttrBool, "collaboration", false)
|
||||
r.addAttr("gscCollabPolicyName", "policyName", AttrString, "collaboration", false)
|
||||
r.addAttr("gscCollabPolicyScope", "policyScope", AttrStringMulti, "collaboration", false)
|
||||
r.addAttr("gscCollabPolicyActions", "policyActions", AttrStringMulti, "collaboration", false)
|
||||
r.addAttr("gscCollabPolicyStatus", "policyStatus", AttrString, "collaboration", false)
|
||||
r.addAttr("gscCollabMaxTeamSize", "maxTeamSize", AttrInt, "collaboration", false)
|
||||
r.addAttr("gscCollabGuestAccessEnabled", "guestAccessEnabled", AttrBool, "collaboration", false)
|
||||
|
||||
// ── barriers (9) ───────────────────────────────────────────
|
||||
r.addAttr("gscBarrierEnabled", "enabled", AttrBool, "barriers", false)
|
||||
r.addAttr("gscBarrierSegmentDN", "segmentDN", AttrDNMulti, "barriers", false)
|
||||
r.addAttr("gscBarrierSegmentName", "segmentName", AttrString, "barriers", false)
|
||||
r.addAttr("gscBarrierSegmentMembers", "segmentMembers", AttrDNMulti, "barriers", false)
|
||||
r.addAttr("gscBarrierPolicyName", "policyName", AttrString, "barriers", false)
|
||||
r.addAttr("gscBarrierPolicyType", "policyType", AttrString, "barriers", false)
|
||||
r.addAttr("gscBarrierPolicySegments", "policySegments", AttrStringMulti, "barriers", false)
|
||||
r.addAttr("gscBarrierPolicyAction", "policyAction", AttrString, "barriers", false)
|
||||
r.addAttr("gscBarrierPolicyStatus", "policyStatus", AttrString, "barriers", false)
|
||||
|
||||
// ── guest (26) ─────────────────────────────────────────────
|
||||
// identity core
|
||||
r.addAttr("gscGuestEnabled", "enabled", AttrBool, "guest", false)
|
||||
r.addAttr("gscGuestType", "type", AttrString, "guest", false)
|
||||
r.addAttr("gscGuestOrganization", "organization", AttrString, "guest", false)
|
||||
r.addAttr("gscGuestExternalEmail", "externalEmail", AttrString, "guest", false)
|
||||
r.addAttr("gscGuestVerified", "verified", AttrBool, "guest", false)
|
||||
// federation
|
||||
r.addAttr("gscGuestFederatedIdpDN", "federatedIdpDN", AttrDN, "guest", false)
|
||||
r.addAttr("gscGuestFederatedId", "federatedId", AttrString, "guest", false)
|
||||
r.addAttr("gscGuestIdpName", "idpName", AttrString, "guest", false)
|
||||
r.addAttr("gscGuestIdpType", "idpType", AttrString, "guest", false)
|
||||
r.addAttr("gscGuestIdpEntityId", "idpEntityId", AttrString, "guest", false)
|
||||
r.addAttr("gscGuestIdpMetadataURL", "idpMetadataURL", AttrString, "guest", false)
|
||||
r.addAttr("gscGuestIdpDomains", "idpDomains", AttrStringMulti, "guest", false)
|
||||
r.addAttr("gscGuestIdpStatus", "idpStatus", AttrString, "guest", false)
|
||||
// access control
|
||||
r.addAttr("gscGuestAccessScope", "accessScope", AttrStringMulti, "guest", false)
|
||||
r.addAttr("gscGuestPermissionLevel", "permissionLevel", AttrString, "guest", false)
|
||||
r.addAttr("gscGuestResourceDN", "resourceDN", AttrDNMulti, "guest", false)
|
||||
// invitation/audit
|
||||
r.addAttr("gscGuestInvitedBy", "invitedBy", AttrDN, "guest", true)
|
||||
r.addAttr("gscGuestInvitedAt", "invitedAt", AttrTime, "guest", true)
|
||||
r.addAttr("gscGuestExpiresAt", "expiresAt", AttrTime, "guest", false)
|
||||
r.addAttr("gscGuestLastAccessAt", "lastAccessAt", AttrTime, "guest", true)
|
||||
r.addAttr("gscGuestAccessCount", "accessCount", AttrInt, "guest", true)
|
||||
// policy/restrictions
|
||||
r.addAttr("gscGuestPolicyName", "policyName", AttrString, "guest", false)
|
||||
r.addAttr("gscGuestPolicyScope", "policyScope", AttrStringMulti, "guest", false)
|
||||
r.addAttr("gscGuestPolicyAction", "policyAction", AttrString, "guest", false)
|
||||
r.addAttr("gscGuestPolicyStatus", "policyStatus", AttrString, "guest", false)
|
||||
r.addAttr("gscGuestMaxDuration", "maxDuration", AttrInt, "guest", false)
|
||||
|
||||
// ── kms-user (12) ──────────────────────────────────────────
|
||||
r.addAttr("gscKmsEnabled", "enabled", AttrBool, "kms-user", false)
|
||||
r.addAttr("gscKmsRole", "role", AttrString, "kms-user", false)
|
||||
r.addAttr("gscKmsKeyAccess", "keyAccess", AttrStringMulti, "kms-user", false)
|
||||
r.addAttr("gscKmsMaxKeys", "maxKeys", AttrInt, "kms-user", false)
|
||||
r.addAttr("gscKmsAllowedAlgorithms", "allowedAlgorithms", AttrStringMulti, "kms-user", false)
|
||||
r.addAttr("gscKmsAllowedOperations", "allowedOperations", AttrStringMulti, "kms-user", false)
|
||||
r.addAttr("gscKmsApprovalRequired", "approvalRequired", AttrBool, "kms-user", false)
|
||||
r.addAttr("gscKmsAuditEnabled", "auditEnabled", AttrBool, "kms-user", false)
|
||||
r.addAttr("gscKmsLastKeyAccess", "lastKeyAccess", AttrTime, "kms-user", true)
|
||||
r.addAttr("gscKmsKeyCount", "keyCount", AttrInt, "kms-user", true)
|
||||
r.addAttr("gscKmsPolicyDN", "policyDN", AttrDNMulti, "kms-user", false)
|
||||
r.addAttr("gscKmsHsmAccess", "hsmAccess", AttrBool, "kms-user", false)
|
||||
|
||||
// ── kms-tenant (12) ────────────────────────────────────────
|
||||
r.addAttr("gscKmsTenantEnabled", "enabled", AttrBool, "kms-tenant", false)
|
||||
r.addAttr("gscKmsTenantMaxKeys", "maxKeys", AttrInt, "kms-tenant", false)
|
||||
r.addAttr("gscKmsTenantAllowedAlgorithms", "allowedAlgorithms", AttrStringMulti, "kms-tenant", false)
|
||||
r.addAttr("gscKmsTenantKeyRotationDays", "keyRotationDays", AttrInt, "kms-tenant", false)
|
||||
r.addAttr("gscKmsTenantHsmEnabled", "hsmEnabled", AttrBool, "kms-tenant", false)
|
||||
r.addAttr("gscKmsTenantHsmPartition", "hsmPartition", AttrString, "kms-tenant", false)
|
||||
r.addAttr("gscKmsTenantAutoRotate", "autoRotate", AttrBool, "kms-tenant", false)
|
||||
r.addAttr("gscKmsTenantKeyCount", "keyCount", AttrInt, "kms-tenant", true)
|
||||
r.addAttr("gscKmsTenantQuota", "quota", AttrInt, "kms-tenant", false)
|
||||
r.addAttr("gscKmsTenantDefaultAlgorithm", "defaultAlgorithm", AttrString, "kms-tenant", false)
|
||||
r.addAttr("gscKmsTenantDefaultKeyLength", "defaultKeyLength", AttrInt, "kms-tenant", false)
|
||||
r.addAttr("gscKmsTenantPolicyDN", "policyDN", AttrDNMulti, "kms-tenant", false)
|
||||
|
||||
// ── managed-key (21) ───────────────────────────────────────
|
||||
r.addAttr("gscKeyId", "keyId", AttrString, "managed-key", false)
|
||||
r.addAttr("gscKeyName", "keyName", AttrString, "managed-key", false)
|
||||
r.addAttr("gscKeyAlgorithm", "algorithm", AttrString, "managed-key", false)
|
||||
r.addAttr("gscKeyLength", "keyLength", AttrInt, "managed-key", false)
|
||||
r.addAttr("gscKeyType", "keyType", AttrString, "managed-key", false)
|
||||
r.addAttr("gscKeyStatus", "status", AttrString, "managed-key", false)
|
||||
r.addAttr("gscKeyCreatedAt", "createdAt", AttrTime, "managed-key", true)
|
||||
r.addAttr("gscKeyExpiresAt", "expiresAt", AttrTime, "managed-key", false)
|
||||
r.addAttr("gscKeyRotatedAt", "rotatedAt", AttrTime, "managed-key", true)
|
||||
r.addAttr("gscKeyOwnerDN", "ownerDN", AttrDN, "managed-key", false)
|
||||
r.addAttr("gscKeyTenantDN", "tenantDN", AttrDN, "managed-key", false)
|
||||
r.addAttr("gscKeyOperations", "operations", AttrStringMulti, "managed-key", false)
|
||||
r.addAttr("gscKeyMaterial", "material", AttrString, "managed-key", false)
|
||||
r.addAttr("gscKeyPublicKey", "publicKey", AttrString, "managed-key", false)
|
||||
r.addAttr("gscKeyFingerprint", "fingerprint", AttrString, "managed-key", true)
|
||||
r.addAttr("gscKeyVersion", "version", AttrInt, "managed-key", false)
|
||||
r.addAttr("gscKeyPreviousVersionDN", "previousVersionDN", AttrDN, "managed-key", false)
|
||||
r.addAttr("gscKeyHsmBacked", "hsmBacked", AttrBool, "managed-key", false)
|
||||
r.addAttr("gscKeyHsmSlot", "hsmSlot", AttrString, "managed-key", false)
|
||||
r.addAttr("gscKeyAutoRotate", "autoRotate", AttrBool, "managed-key", false)
|
||||
r.addAttr("gscKeyRotationDays", "rotationDays", AttrInt, "managed-key", false)
|
||||
|
||||
// ── kms-policy (15) ────────────────────────────────────────
|
||||
r.addAttr("gscKmsPolicyId", "policyId", AttrString, "kms-policy", false)
|
||||
r.addAttr("gscKmsPolicyName", "policyName", AttrString, "kms-policy", false)
|
||||
r.addAttr("gscKmsPolicyType", "policyType", AttrString, "kms-policy", false)
|
||||
r.addAttr("gscKmsPolicyEffect", "effect", AttrString, "kms-policy", false)
|
||||
r.addAttr("gscKmsPolicyPrincipalDN", "principalDN", AttrDNMulti, "kms-policy", false)
|
||||
r.addAttr("gscKmsPolicyResourceDN", "resourceDN", AttrDNMulti, "kms-policy", false)
|
||||
r.addAttr("gscKmsPolicyOperations", "operations", AttrStringMulti, "kms-policy", false)
|
||||
r.addAttr("gscKmsPolicyConditions", "conditions", AttrStringMulti, "kms-policy", false)
|
||||
r.addAttr("gscKmsPolicyPriority", "priority", AttrInt, "kms-policy", false)
|
||||
r.addAttr("gscKmsPolicyStatus", "status", AttrString, "kms-policy", false)
|
||||
r.addAttr("gscKmsPolicyCreatedAt", "createdAt", AttrTime, "kms-policy", true)
|
||||
r.addAttr("gscKmsPolicyModifiedAt", "modifiedAt", AttrTime, "kms-policy", true)
|
||||
r.addAttr("gscKmsPolicyTenantDN", "tenantDN", AttrDN, "kms-policy", false)
|
||||
r.addAttr("gscKmsPolicyMaxKeyAge", "maxKeyAge", AttrInt, "kms-policy", false)
|
||||
r.addAttr("gscKmsPolicyRequireHsm", "requireHsm", AttrBool, "kms-policy", false)
|
||||
|
||||
// ── hsm-config (10) ────────────────────────────────────────
|
||||
r.addAttr("gscHsmConfigId", "configId", AttrString, "hsm-config", false)
|
||||
r.addAttr("gscHsmConfigName", "configName", AttrString, "hsm-config", false)
|
||||
r.addAttr("gscHsmConfigType", "type", AttrString, "hsm-config", false)
|
||||
r.addAttr("gscHsmConfigVendor", "vendor", AttrString, "hsm-config", false)
|
||||
r.addAttr("gscHsmConfigModel", "model", AttrString, "hsm-config", false)
|
||||
r.addAttr("gscHsmConfigConnectionString", "connectionString", AttrString, "hsm-config", false)
|
||||
r.addAttr("gscHsmConfigSlots", "slots", AttrStringMulti, "hsm-config", false)
|
||||
r.addAttr("gscHsmConfigStatus", "status", AttrString, "hsm-config", false)
|
||||
r.addAttr("gscHsmConfigMaxKeys", "maxKeys", AttrInt, "hsm-config", false)
|
||||
r.addAttr("gscHsmConfigTenantDN", "tenantDN", AttrDNMulti, "hsm-config", false)
|
||||
}
|
||||
112
internal/schema/entities.go
Normal file
112
internal/schema/entities.go
Normal file
@@ -0,0 +1,112 @@
|
||||
package schema
|
||||
|
||||
// registerEntities registers all 18 entity type definitions for generic CRUD.
|
||||
func (r *Registry) registerEntities() {
|
||||
r.addEntityType("tenant", "Organization tenant",
|
||||
[]string{"top", "gscTenant"},
|
||||
"ou=tenants", "gscTenantId",
|
||||
"(objectClass=gscTenant)", "tenant",
|
||||
[]string{"gscTenantId", "gscTenantName"})
|
||||
|
||||
r.addEntityType("resource", "Shared resource (room, equipment)",
|
||||
[]string{"top", "gscResource"},
|
||||
"ou=tenants", "gscResourceId",
|
||||
"(objectClass=gscResource)", "resource",
|
||||
[]string{"gscResourceId", "gscResourceName", "gscResourceType"})
|
||||
|
||||
r.addEntityType("dlp-policy", "Data loss prevention policy",
|
||||
[]string{"top", "gscDlpPolicy"},
|
||||
"ou=dlp,ou=compliance", "cn",
|
||||
"(objectClass=gscDlpPolicy)", "dlp",
|
||||
[]string{"gscDlpPolicyName"})
|
||||
|
||||
r.addEntityType("sensitivity-label", "Sensitivity classification label",
|
||||
[]string{"top", "gscSensitivityLabel"},
|
||||
"ou=sensitivity,ou=compliance", "cn",
|
||||
"(objectClass=gscSensitivityLabel)", "sensitivity",
|
||||
[]string{"gscSensitivityLabelName"})
|
||||
|
||||
r.addEntityType("encryption-policy", "Encryption policy",
|
||||
[]string{"top", "gscEncryptionPolicy"},
|
||||
"ou=encryption,ou=compliance", "cn",
|
||||
"(objectClass=gscEncryptionPolicy)", "encryption",
|
||||
[]string{"gscEncryptionPolicyName"})
|
||||
|
||||
r.addEntityType("retention-policy", "Data retention policy",
|
||||
[]string{"top", "gscRetentionPolicy"},
|
||||
"ou=retention,ou=compliance", "cn",
|
||||
"(objectClass=gscRetentionPolicy)", "retention",
|
||||
[]string{"gscRetentionPolicyName"})
|
||||
|
||||
r.addEntityType("ediscovery-case", "eDiscovery case",
|
||||
[]string{"top", "gscEDiscoveryCase"},
|
||||
"ou=ediscovery,ou=compliance", "cn",
|
||||
"(objectClass=gscEDiscoveryCase)", "ediscovery",
|
||||
[]string{"gscEDiscoveryCaseName"})
|
||||
|
||||
r.addEntityType("ediscovery-hold", "eDiscovery legal hold",
|
||||
[]string{"top", "gscEDiscoveryHold"},
|
||||
"ou=ediscovery,ou=compliance", "cn",
|
||||
"(objectClass=gscEDiscoveryHold)", "ediscovery",
|
||||
[]string{"gscEDiscoveryHoldName"})
|
||||
|
||||
r.addEntityType("audit-policy", "Audit logging policy",
|
||||
[]string{"top", "gscAuditPolicy"},
|
||||
"ou=audit,ou=compliance", "cn",
|
||||
"(objectClass=gscAuditPolicy)", "audit",
|
||||
[]string{"gscAuditPolicyName"})
|
||||
|
||||
r.addEntityType("ca-policy", "Conditional access policy",
|
||||
[]string{"top", "gscConditionalAccessPolicy"},
|
||||
"ou=iam,ou=compliance", "cn",
|
||||
"(objectClass=gscConditionalAccessPolicy)", "iam",
|
||||
[]string{"gscIAMCAPolicyName"})
|
||||
|
||||
r.addEntityType("collab-policy", "Collaboration policy",
|
||||
[]string{"top", "gscCollaborationPolicy"},
|
||||
"ou=collaboration,ou=compliance", "cn",
|
||||
"(objectClass=gscCollaborationPolicy)", "collaboration",
|
||||
[]string{"gscCollabPolicyName"})
|
||||
|
||||
r.addEntityType("barrier-segment", "Information barrier segment",
|
||||
[]string{"top", "gscBarrierSegment"},
|
||||
"ou=barriers,ou=compliance", "cn",
|
||||
"(objectClass=gscBarrierSegment)", "barriers",
|
||||
[]string{"gscBarrierSegmentName"})
|
||||
|
||||
r.addEntityType("barrier-policy", "Information barrier policy",
|
||||
[]string{"top", "gscBarrierPolicy"},
|
||||
"ou=barriers,ou=compliance", "cn",
|
||||
"(objectClass=gscBarrierPolicy)", "barriers",
|
||||
[]string{"gscBarrierPolicyName"})
|
||||
|
||||
r.addEntityType("guest-policy", "Guest access policy",
|
||||
[]string{"top", "gscGuestPolicy"},
|
||||
"ou=policies,ou=guests", "cn",
|
||||
"(objectClass=gscGuestPolicy)", "guest",
|
||||
[]string{"gscGuestPolicyName"})
|
||||
|
||||
r.addEntityType("federated-idp", "Federated identity provider",
|
||||
[]string{"top", "gscFederatedIdp"},
|
||||
"ou=idps,ou=guests", "cn",
|
||||
"(objectClass=gscFederatedIdp)", "guest",
|
||||
[]string{"gscGuestIdpName"})
|
||||
|
||||
r.addEntityType("managed-key", "Managed encryption key",
|
||||
[]string{"top", "gscManagedKey"},
|
||||
"ou=keys,ou=keymanagement", "gscKeyId",
|
||||
"(objectClass=gscManagedKey)", "managed-key",
|
||||
[]string{"gscKeyId", "gscKeyName", "gscKeyAlgorithm"})
|
||||
|
||||
r.addEntityType("kms-policy", "Key management policy",
|
||||
[]string{"top", "gscKmsPolicy"},
|
||||
"ou=policies,ou=keymanagement", "gscKmsPolicyId",
|
||||
"(objectClass=gscKmsPolicy)", "kms-policy",
|
||||
[]string{"gscKmsPolicyId", "gscKmsPolicyName"})
|
||||
|
||||
r.addEntityType("hsm-config", "HSM hardware configuration",
|
||||
[]string{"top", "gscHsmConfig"},
|
||||
"ou=hsmconfigs,ou=keymanagement", "gscHsmConfigId",
|
||||
"(objectClass=gscHsmConfig)", "hsm-config",
|
||||
[]string{"gscHsmConfigId", "gscHsmConfigName"})
|
||||
}
|
||||
230
internal/schema/objectclasses.go
Normal file
230
internal/schema/objectclasses.go
Normal file
@@ -0,0 +1,230 @@
|
||||
package schema
|
||||
|
||||
// registerObjectClasses registers all 45 GoSec LDAP objectClass definitions.
|
||||
func (r *Registry) registerObjectClasses() {
|
||||
// ── AUXILIARY user objectClasses (21) ────────────────────────
|
||||
|
||||
r.addObjectClass("gscTenantUser", "AUXILIARY",
|
||||
[]string{"gscTenantId"},
|
||||
[]string{"gscTenantName", "gscTenantDomain", "gscTenantStatus", "gscUserTenantHash", "gscUserTenantHashSalt", "gscUserTenantHashVersion", "gscUserTenantHashCreatedAt", "gscUserTenantHashVerifiedAt", "gscCustomerId", "gscSID", "gscSIDCustomerPart", "gscSIDTenantPart", "gscSIDSpecial1", "gscSIDSpecial2", "gscSIDUserPart", "gscCreatedAt", "gscModifiedAt", "gscCreatedBy", "gscModifiedBy"},
|
||||
"tenant")
|
||||
|
||||
r.addObjectClass("gscMailUser", "AUXILIARY",
|
||||
[]string{"gscMailEnabled"},
|
||||
[]string{"gscMailQuota", "gscMailAlias", "gscMailForward", "gscMailAutoReply", "gscMailAutoReplyMessage", "gscMailTransport", "gscMailDomain"},
|
||||
"mail")
|
||||
|
||||
r.addObjectClass("gscConfUser", "AUXILIARY",
|
||||
[]string{"gscConfEnabled"},
|
||||
[]string{"gscConfRole", "gscConfMaxParticipants", "gscConfRecordingEnabled", "gscConfDefaultRoom"},
|
||||
"conf")
|
||||
|
||||
r.addObjectClass("gscFtpUser", "AUXILIARY",
|
||||
[]string{"gscFtpEnabled"},
|
||||
[]string{"gscFtpQuota", "gscFtpHomeDir", "gscFtpUploadBandwidth", "gscFtpDownloadBandwidth", "gscFtpAllowedIPs"},
|
||||
"ftp")
|
||||
|
||||
r.addObjectClass("gscFileUser", "AUXILIARY",
|
||||
[]string{"gscFileEnabled"},
|
||||
[]string{"gscFileQuota", "gscFileHomeDir", "gscFileVersioning", "gscFileMaxFileSize"},
|
||||
"file")
|
||||
|
||||
r.addObjectClass("gscShareUser", "AUXILIARY",
|
||||
[]string{"gscShareEnabled"},
|
||||
[]string{"gscShareExternalEnabled", "gscShareMaxRecipients", "gscShareDefaultExpiry", "gscSharePasswordRequired"},
|
||||
"sharing")
|
||||
|
||||
r.addObjectClass("gscCalUser", "AUXILIARY",
|
||||
[]string{"gscCalEnabled"},
|
||||
[]string{"gscCalDefaultCalendar", "gscCalTimezone", "gscCalFreeBusyPublic", "gscCalDelegates"},
|
||||
"calendar")
|
||||
|
||||
r.addObjectClass("gscTelUser", "AUXILIARY",
|
||||
[]string{"gscTelEnabled"},
|
||||
[]string{"gscTelExtension", "gscTelDID", "gscTelVoicemailEnabled", "gscTelVoicemailPin", "gscTelCallForward", "gscTelCallGroup", "gscTelRecordCalls"},
|
||||
"telephony")
|
||||
|
||||
r.addObjectClass("gscContactsUser", "AUXILIARY",
|
||||
[]string{"gscContactsEnabled"},
|
||||
[]string{"gscContactsShared", "gscContactsMaxContacts", "gscContactsExportEnabled"},
|
||||
"contacts")
|
||||
|
||||
r.addObjectClass("gscAIUser", "AUXILIARY",
|
||||
[]string{"gscAIEnabled"},
|
||||
[]string{"gscAIModel", "gscAIMaxTokens", "gscAIFeatures", "gscAIUsageQuota"},
|
||||
"ai")
|
||||
|
||||
r.addObjectClass("gscDlpUser", "AUXILIARY",
|
||||
[]string{"gscDlpEnabled"},
|
||||
[]string{"gscDlpPolicyDN", "gscDlpExempt"},
|
||||
"dlp")
|
||||
|
||||
r.addObjectClass("gscSensitivityUser", "AUXILIARY",
|
||||
[]string{"gscSensitivityEnabled"},
|
||||
[]string{"gscSensitivityDefaultLabel"},
|
||||
"sensitivity")
|
||||
|
||||
r.addObjectClass("gscEncryptionUser", "AUXILIARY",
|
||||
[]string{"gscEncryptionEnabled"},
|
||||
[]string{"gscEncryptionKeyDN"},
|
||||
"encryption")
|
||||
|
||||
r.addObjectClass("gscRetentionUser", "AUXILIARY",
|
||||
[]string{"gscRetentionEnabled"},
|
||||
[]string{"gscRetentionPolicyDN"},
|
||||
"retention")
|
||||
|
||||
r.addObjectClass("gscEDiscoveryUser", "AUXILIARY",
|
||||
[]string{"gscEDiscoveryEnabled"},
|
||||
[]string{"gscEDiscoveryCustodian"},
|
||||
"ediscovery")
|
||||
|
||||
r.addObjectClass("gscAdvancedAuditUser", "AUXILIARY",
|
||||
[]string{"gscAuditEnabled"},
|
||||
[]string{"gscAuditLevel"},
|
||||
"audit")
|
||||
|
||||
r.addObjectClass("gscIAMUser", "AUXILIARY",
|
||||
[]string{"gscIAMEnabled"},
|
||||
[]string{"gscIAMMFARequired", "gscIAMMFAMethod", "gscIAMPasswordPolicy", "gscIAMSessionTimeout", "gscIAMMaxSessions", "gscIAMIPRestrictions", "gscIAMRiskLevel"},
|
||||
"iam")
|
||||
|
||||
r.addObjectClass("gscCollaborationUser", "AUXILIARY",
|
||||
[]string{"gscCollabEnabled"},
|
||||
[]string{"gscCollabTeamsEnabled", "gscCollabChannelsEnabled", "gscCollabExternalEnabled"},
|
||||
"collaboration")
|
||||
|
||||
r.addObjectClass("gscBarrierUser", "AUXILIARY",
|
||||
[]string{"gscBarrierEnabled"},
|
||||
[]string{"gscBarrierSegmentDN"},
|
||||
"barriers")
|
||||
|
||||
r.addObjectClass("gscGuestUser", "AUXILIARY",
|
||||
[]string{"gscGuestEnabled"},
|
||||
[]string{"gscGuestType", "gscGuestOrganization", "gscGuestExternalEmail", "gscGuestVerified", "gscGuestFederatedIdpDN", "gscGuestFederatedId", "gscGuestAccessScope", "gscGuestPermissionLevel", "gscGuestResourceDN", "gscGuestInvitedBy", "gscGuestInvitedAt", "gscGuestExpiresAt", "gscGuestLastAccessAt", "gscGuestAccessCount"},
|
||||
"guest")
|
||||
|
||||
r.addObjectClass("gscKmsUser", "AUXILIARY",
|
||||
[]string{"gscKmsEnabled"},
|
||||
[]string{"gscKmsRole", "gscKmsKeyAccess", "gscKmsMaxKeys", "gscKmsAllowedAlgorithms", "gscKmsAllowedOperations", "gscKmsApprovalRequired", "gscKmsAuditEnabled", "gscKmsLastKeyAccess", "gscKmsKeyCount", "gscKmsPolicyDN", "gscKmsHsmAccess"},
|
||||
"kms-user")
|
||||
|
||||
// ── STRUCTURAL entity objectClasses (18) ────────────────────
|
||||
|
||||
r.addObjectClass("gscTenant", "STRUCTURAL",
|
||||
[]string{"gscTenantId", "gscTenantName"},
|
||||
[]string{"gscTenantDomain", "gscTenantStatus", "gscTenantQuota", "gscTenantMaxUsers", "gscTenantCreatedAt", "gscTenantServices", "gscTenantAdminDN", "gscTenantParentDN", "gscDescription", "gscEnabled", "gscNotes", "gscCreatedAt", "gscModifiedAt", "gscCreatedBy", "gscModifiedBy"},
|
||||
"tenant")
|
||||
|
||||
r.addObjectClass("gscResource", "STRUCTURAL",
|
||||
[]string{"gscResourceId", "gscResourceName", "gscResourceType"},
|
||||
[]string{"gscResourceEmail", "gscResourceCapacity", "gscResourceLocation", "gscResourceBookable", "gscResourceApprovalRequired", "gscResourceOwnerDN", "gscDescription", "gscEnabled", "gscCreatedAt", "gscModifiedAt"},
|
||||
"resource")
|
||||
|
||||
r.addObjectClass("gscDlpPolicy", "STRUCTURAL",
|
||||
[]string{"gscDlpPolicyName"},
|
||||
[]string{"gscDlpPolicyType", "gscDlpPolicyRules", "gscDlpPolicyAction", "gscDlpPolicyPriority", "gscDlpPolicyScope", "gscDlpPolicyStatus", "gscDescription", "gscEnabled", "gscCreatedAt", "gscModifiedAt"},
|
||||
"dlp")
|
||||
|
||||
r.addObjectClass("gscSensitivityLabel", "STRUCTURAL",
|
||||
[]string{"gscSensitivityLabelName"},
|
||||
[]string{"gscSensitivityLabelPriority", "gscSensitivityLabelColor", "gscSensitivityLabelTooltip", "gscSensitivityLabelScope", "gscSensitivityEncryptionRequired", "gscSensitivityWatermark", "gscDescription", "gscEnabled", "gscCreatedAt", "gscModifiedAt"},
|
||||
"sensitivity")
|
||||
|
||||
r.addObjectClass("gscEncryptionPolicy", "STRUCTURAL",
|
||||
[]string{"gscEncryptionPolicyName"},
|
||||
[]string{"gscEncryptionPolicyType", "gscEncryptionAlgorithm", "gscEncryptionKeyLength", "gscEncryptionScope", "gscEncryptionPolicyStatus", "gscDescription", "gscEnabled", "gscCreatedAt", "gscModifiedAt"},
|
||||
"encryption")
|
||||
|
||||
r.addObjectClass("gscRetentionPolicy", "STRUCTURAL",
|
||||
[]string{"gscRetentionPolicyName"},
|
||||
[]string{"gscRetentionPolicyType", "gscRetentionDuration", "gscRetentionAction", "gscRetentionScope", "gscRetentionPolicyStatus", "gscRetentionExcludeFolders", "gscRetentionLegalHold", "gscDescription", "gscEnabled", "gscCreatedAt", "gscModifiedAt"},
|
||||
"retention")
|
||||
|
||||
r.addObjectClass("gscEDiscoveryCase", "STRUCTURAL",
|
||||
[]string{"gscEDiscoveryCaseName"},
|
||||
[]string{"gscEDiscoveryCaseStatus", "gscEDiscoveryCaseCreatedAt", "gscEDiscoveryCaseClosedAt", "gscDescription", "gscEnabled", "gscCreatedAt", "gscModifiedAt"},
|
||||
"ediscovery")
|
||||
|
||||
r.addObjectClass("gscEDiscoveryHold", "STRUCTURAL",
|
||||
[]string{"gscEDiscoveryHoldName"},
|
||||
[]string{"gscEDiscoveryHoldScope", "gscEDiscoveryHoldStatus", "gscEDiscoveryHoldCreatedAt", "gscEDiscoverySearchQuery", "gscDescription", "gscEnabled", "gscCreatedAt", "gscModifiedAt"},
|
||||
"ediscovery")
|
||||
|
||||
r.addObjectClass("gscAuditPolicy", "STRUCTURAL",
|
||||
[]string{"gscAuditPolicyName"},
|
||||
[]string{"gscAuditPolicyScope", "gscAuditPolicyActions", "gscAuditPolicyStatus", "gscAuditRetentionDays", "gscAuditAlertEnabled", "gscAuditAlertRecipients", "gscDescription", "gscEnabled", "gscCreatedAt", "gscModifiedAt"},
|
||||
"audit")
|
||||
|
||||
r.addObjectClass("gscConditionalAccessPolicy", "STRUCTURAL",
|
||||
[]string{"gscIAMCAPolicyName"},
|
||||
[]string{"gscIAMCAPolicyConditions", "gscIAMCAPolicyActions", "gscIAMCAPolicyStatus", "gscDescription", "gscEnabled", "gscCreatedAt", "gscModifiedAt"},
|
||||
"iam")
|
||||
|
||||
r.addObjectClass("gscCollaborationPolicy", "STRUCTURAL",
|
||||
[]string{"gscCollabPolicyName"},
|
||||
[]string{"gscCollabPolicyScope", "gscCollabPolicyActions", "gscCollabPolicyStatus", "gscCollabMaxTeamSize", "gscCollabGuestAccessEnabled", "gscDescription", "gscEnabled", "gscCreatedAt", "gscModifiedAt"},
|
||||
"collaboration")
|
||||
|
||||
r.addObjectClass("gscBarrierSegment", "STRUCTURAL",
|
||||
[]string{"gscBarrierSegmentName"},
|
||||
[]string{"gscBarrierSegmentMembers", "gscDescription", "gscEnabled", "gscCreatedAt", "gscModifiedAt"},
|
||||
"barriers")
|
||||
|
||||
r.addObjectClass("gscBarrierPolicy", "STRUCTURAL",
|
||||
[]string{"gscBarrierPolicyName"},
|
||||
[]string{"gscBarrierPolicyType", "gscBarrierPolicySegments", "gscBarrierPolicyAction", "gscBarrierPolicyStatus", "gscDescription", "gscEnabled", "gscCreatedAt", "gscModifiedAt"},
|
||||
"barriers")
|
||||
|
||||
r.addObjectClass("gscGuestPolicy", "STRUCTURAL",
|
||||
[]string{"gscGuestPolicyName"},
|
||||
[]string{"gscGuestPolicyScope", "gscGuestPolicyAction", "gscGuestPolicyStatus", "gscGuestMaxDuration", "gscDescription", "gscEnabled", "gscCreatedAt", "gscModifiedAt"},
|
||||
"guest")
|
||||
|
||||
r.addObjectClass("gscFederatedIdp", "STRUCTURAL",
|
||||
[]string{"gscGuestIdpName"},
|
||||
[]string{"gscGuestIdpType", "gscGuestIdpEntityId", "gscGuestIdpMetadataURL", "gscGuestIdpDomains", "gscGuestIdpStatus", "gscDescription", "gscEnabled", "gscCreatedAt", "gscModifiedAt"},
|
||||
"guest")
|
||||
|
||||
r.addObjectClass("gscManagedKey", "STRUCTURAL",
|
||||
[]string{"gscKeyId", "gscKeyName", "gscKeyAlgorithm"},
|
||||
[]string{"gscKeyLength", "gscKeyType", "gscKeyStatus", "gscKeyCreatedAt", "gscKeyExpiresAt", "gscKeyRotatedAt", "gscKeyOwnerDN", "gscKeyTenantDN", "gscKeyOperations", "gscKeyMaterial", "gscKeyPublicKey", "gscKeyFingerprint", "gscKeyVersion", "gscKeyPreviousVersionDN", "gscKeyHsmBacked", "gscKeyHsmSlot", "gscKeyAutoRotate", "gscKeyRotationDays"},
|
||||
"managed-key")
|
||||
|
||||
r.addObjectClass("gscKmsPolicy", "STRUCTURAL",
|
||||
[]string{"gscKmsPolicyId", "gscKmsPolicyName"},
|
||||
[]string{"gscKmsPolicyType", "gscKmsPolicyEffect", "gscKmsPolicyPrincipalDN", "gscKmsPolicyResourceDN", "gscKmsPolicyOperations", "gscKmsPolicyConditions", "gscKmsPolicyPriority", "gscKmsPolicyStatus", "gscKmsPolicyCreatedAt", "gscKmsPolicyModifiedAt", "gscKmsPolicyTenantDN", "gscKmsPolicyMaxKeyAge", "gscKmsPolicyRequireHsm"},
|
||||
"kms-policy")
|
||||
|
||||
r.addObjectClass("gscHsmConfig", "STRUCTURAL",
|
||||
[]string{"gscHsmConfigId", "gscHsmConfigName"},
|
||||
[]string{"gscHsmConfigType", "gscHsmConfigVendor", "gscHsmConfigModel", "gscHsmConfigConnectionString", "gscHsmConfigSlots", "gscHsmConfigStatus", "gscHsmConfigMaxKeys", "gscHsmConfigTenantDN"},
|
||||
"hsm-config")
|
||||
|
||||
// ── AUXILIARY object objectClasses (6) ──────────────────────
|
||||
|
||||
r.addObjectClass("gscAuditObject", "AUXILIARY",
|
||||
[]string{"gscAuditEnabled"},
|
||||
[]string{"gscAuditLevel", "gscAuditPolicyName"},
|
||||
"audit")
|
||||
|
||||
r.addObjectClass("gscMeetingRoom", "AUXILIARY",
|
||||
[]string{"gscResourceId", "gscResourceType"},
|
||||
[]string{"gscResourceCapacity", "gscResourceLocation", "gscResourceBookable"},
|
||||
"resource")
|
||||
|
||||
r.addObjectClass("gscSharedMailbox", "AUXILIARY",
|
||||
[]string{"gscMailEnabled"},
|
||||
[]string{"gscMailQuota", "gscMailAlias", "gscMailDomain"},
|
||||
"mail")
|
||||
|
||||
r.addObjectClass("gscEquipment", "AUXILIARY",
|
||||
[]string{"gscResourceId", "gscResourceType"},
|
||||
[]string{"gscResourceName", "gscResourceLocation", "gscResourceBookable"},
|
||||
"resource")
|
||||
|
||||
r.addObjectClass("gscKmsTenant", "AUXILIARY",
|
||||
[]string{"gscKmsTenantEnabled"},
|
||||
[]string{"gscKmsTenantMaxKeys", "gscKmsTenantAllowedAlgorithms", "gscKmsTenantKeyRotationDays", "gscKmsTenantHsmEnabled", "gscKmsTenantHsmPartition", "gscKmsTenantAutoRotate", "gscKmsTenantKeyCount", "gscKmsTenantQuota", "gscKmsTenantDefaultAlgorithm", "gscKmsTenantDefaultKeyLength", "gscKmsTenantPolicyDN"},
|
||||
"kms-tenant")
|
||||
}
|
||||
273
internal/schema/registry.go
Normal file
273
internal/schema/registry.go
Normal file
@@ -0,0 +1,273 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Registry is the central schema registry for all GoSec LDAP attributes,
|
||||
// objectClasses, and entity types.
|
||||
type Registry struct {
|
||||
attrs map[string]*AttrDef // ldapName → AttrDef
|
||||
attrsByJSON map[string]*AttrDef // "domain:jsonName" → AttrDef
|
||||
domainAttrs map[string][]*AttrDef // domain → list of attrs
|
||||
objectClasses map[string]*ObjectClassDef // OC name → ObjectClassDef
|
||||
domainOC map[string]string // domain → auxiliary user OC name
|
||||
entityTypes map[string]*EntityTypeDef // entity name → EntityTypeDef
|
||||
}
|
||||
|
||||
// NewRegistry creates and populates the schema registry
|
||||
func NewRegistry() *Registry {
|
||||
r := &Registry{
|
||||
attrs: make(map[string]*AttrDef),
|
||||
attrsByJSON: make(map[string]*AttrDef),
|
||||
domainAttrs: make(map[string][]*AttrDef),
|
||||
objectClasses: make(map[string]*ObjectClassDef),
|
||||
domainOC: make(map[string]string),
|
||||
entityTypes: make(map[string]*EntityTypeDef),
|
||||
}
|
||||
r.registerAttributes()
|
||||
r.registerObjectClasses()
|
||||
r.registerEntities()
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *Registry) addAttr(ldapName, jsonName string, typ AttrType, domain string, readOnly bool) {
|
||||
def := &AttrDef{
|
||||
LDAPName: ldapName,
|
||||
JSONName: jsonName,
|
||||
Type: typ,
|
||||
Domain: domain,
|
||||
ReadOnly: readOnly,
|
||||
}
|
||||
r.attrs[ldapName] = def
|
||||
r.attrsByJSON[domain+":"+jsonName] = def
|
||||
r.domainAttrs[domain] = append(r.domainAttrs[domain], def)
|
||||
}
|
||||
|
||||
func (r *Registry) addObjectClass(name, kind string, must, may []string, domain string) {
|
||||
r.objectClasses[name] = &ObjectClassDef{
|
||||
Name: name,
|
||||
Kind: kind,
|
||||
Must: must,
|
||||
May: may,
|
||||
Domain: domain,
|
||||
}
|
||||
// Map domain → auxiliary user objectClass (first AUXILIARY wins)
|
||||
if kind == "AUXILIARY" {
|
||||
if _, exists := r.domainOC[domain]; !exists {
|
||||
r.domainOC[domain] = name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Registry) addEntityType(name, description string, objectClasses []string, baseDN, rdnAttr, searchFilter, domain string, requiredAttrs []string) {
|
||||
r.entityTypes[name] = &EntityTypeDef{
|
||||
Name: name,
|
||||
Description: description,
|
||||
ObjectClasses: objectClasses,
|
||||
BaseDN: baseDN,
|
||||
RDNAttribute: rdnAttr,
|
||||
SearchFilter: searchFilter,
|
||||
Domain: domain,
|
||||
RequiredAttrs: requiredAttrs,
|
||||
}
|
||||
}
|
||||
|
||||
// GetAttr returns an attribute definition by LDAP name
|
||||
func (r *Registry) GetAttr(ldapName string) *AttrDef {
|
||||
return r.attrs[ldapName]
|
||||
}
|
||||
|
||||
// GetAttrByJSON returns an attribute definition by domain and JSON name
|
||||
func (r *Registry) GetAttrByJSON(domain, jsonName string) *AttrDef {
|
||||
return r.attrsByJSON[domain+":"+jsonName]
|
||||
}
|
||||
|
||||
// AttrsForDomain returns all attribute definitions for a domain
|
||||
func (r *Registry) AttrsForDomain(domain string) []*AttrDef {
|
||||
return r.domainAttrs[domain]
|
||||
}
|
||||
|
||||
// AllDomains returns all registered domain names
|
||||
func (r *Registry) AllDomains() []string {
|
||||
domains := make([]string, 0, len(r.domainAttrs))
|
||||
for d := range r.domainAttrs {
|
||||
domains = append(domains, d)
|
||||
}
|
||||
return domains
|
||||
}
|
||||
|
||||
// AllUserAttrs returns all gsc* LDAP attribute names for user search
|
||||
func (r *Registry) AllUserAttrs() []string {
|
||||
attrs := make([]string, 0, len(r.attrs))
|
||||
for name := range r.attrs {
|
||||
attrs = append(attrs, name)
|
||||
}
|
||||
return attrs
|
||||
}
|
||||
|
||||
// UserOCForDomain returns the auxiliary objectClass name for a user service domain
|
||||
func (r *Registry) UserOCForDomain(domain string) string {
|
||||
return r.domainOC[domain]
|
||||
}
|
||||
|
||||
// RequiredOCsForAttrs determines which objectClasses are needed for a set of LDAP attributes
|
||||
func (r *Registry) RequiredOCsForAttrs(ldapAttrNames []string) []string {
|
||||
needed := make(map[string]bool)
|
||||
attrSet := make(map[string]bool, len(ldapAttrNames))
|
||||
for _, a := range ldapAttrNames {
|
||||
attrSet[a] = true
|
||||
}
|
||||
|
||||
for _, oc := range r.objectClasses {
|
||||
if oc.Kind != "AUXILIARY" {
|
||||
continue
|
||||
}
|
||||
for _, must := range oc.Must {
|
||||
if attrSet[must] {
|
||||
needed[oc.Name] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if needed[oc.Name] {
|
||||
continue
|
||||
}
|
||||
for _, may := range oc.May {
|
||||
if attrSet[may] {
|
||||
needed[oc.Name] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result := make([]string, 0, len(needed))
|
||||
for name := range needed {
|
||||
result = append(result, name)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// GetObjectClass returns an objectClass definition by name
|
||||
func (r *Registry) GetObjectClass(name string) *ObjectClassDef {
|
||||
return r.objectClasses[name]
|
||||
}
|
||||
|
||||
// LDAPValueToGo converts LDAP string values to Go typed values based on attribute type
|
||||
func (r *Registry) LDAPValueToGo(attr *AttrDef, values []string) interface{} {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch attr.Type {
|
||||
case AttrString, AttrDN:
|
||||
return values[0]
|
||||
case AttrStringMulti, AttrDNMulti:
|
||||
return values
|
||||
case AttrInt:
|
||||
if v, err := strconv.Atoi(values[0]); err == nil {
|
||||
return v
|
||||
}
|
||||
return values[0]
|
||||
case AttrBool:
|
||||
return strings.EqualFold(values[0], "TRUE")
|
||||
case AttrTime:
|
||||
// GeneralizedTime format: 20060102150405Z
|
||||
if t, err := time.Parse("20060102150405Z", values[0]); err == nil {
|
||||
return t.Format(time.RFC3339)
|
||||
}
|
||||
return values[0]
|
||||
default:
|
||||
return values[0]
|
||||
}
|
||||
}
|
||||
|
||||
// GoValueToLDAP converts a Go value to LDAP string(s) based on attribute type
|
||||
func (r *Registry) GoValueToLDAP(attr *AttrDef, value interface{}) ([]string, error) {
|
||||
if value == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
switch attr.Type {
|
||||
case AttrString, AttrDN:
|
||||
s, ok := value.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("attribute %s expects string, got %T", attr.LDAPName, value)
|
||||
}
|
||||
return []string{s}, nil
|
||||
|
||||
case AttrStringMulti, AttrDNMulti:
|
||||
switch v := value.(type) {
|
||||
case []string:
|
||||
return v, nil
|
||||
case []interface{}:
|
||||
result := make([]string, 0, len(v))
|
||||
for _, item := range v {
|
||||
s, ok := item.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("attribute %s expects string array, got %T in array", attr.LDAPName, item)
|
||||
}
|
||||
result = append(result, s)
|
||||
}
|
||||
return result, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("attribute %s expects string array, got %T", attr.LDAPName, value)
|
||||
}
|
||||
|
||||
case AttrInt:
|
||||
switch v := value.(type) {
|
||||
case float64:
|
||||
return []string{strconv.Itoa(int(v))}, nil
|
||||
case int:
|
||||
return []string{strconv.Itoa(v)}, nil
|
||||
case string:
|
||||
return []string{v}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("attribute %s expects int, got %T", attr.LDAPName, value)
|
||||
}
|
||||
|
||||
case AttrBool:
|
||||
switch v := value.(type) {
|
||||
case bool:
|
||||
if v {
|
||||
return []string{"TRUE"}, nil
|
||||
}
|
||||
return []string{"FALSE"}, nil
|
||||
case string:
|
||||
return []string{strings.ToUpper(v)}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("attribute %s expects bool, got %T", attr.LDAPName, value)
|
||||
}
|
||||
|
||||
case AttrTime:
|
||||
s, ok := value.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("attribute %s expects time string, got %T", attr.LDAPName, value)
|
||||
}
|
||||
// Accept RFC3339 and convert to GeneralizedTime
|
||||
if t, err := time.Parse(time.RFC3339, s); err == nil {
|
||||
return []string{t.UTC().Format("20060102150405Z")}, nil
|
||||
}
|
||||
// Already GeneralizedTime format
|
||||
return []string{s}, nil
|
||||
|
||||
default:
|
||||
s, ok := value.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("attribute %s: unsupported type %T", attr.LDAPName, value)
|
||||
}
|
||||
return []string{s}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// GetEntityType returns an entity type definition by name
|
||||
func (r *Registry) GetEntityType(name string) *EntityTypeDef {
|
||||
return r.entityTypes[name]
|
||||
}
|
||||
|
||||
// AllEntityTypes returns all registered entity type definitions
|
||||
func (r *Registry) AllEntityTypes() map[string]*EntityTypeDef {
|
||||
return r.entityTypes
|
||||
}
|
||||
44
internal/schema/types.go
Normal file
44
internal/schema/types.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package schema
|
||||
|
||||
// AttrType represents the LDAP attribute value type
|
||||
type AttrType int
|
||||
|
||||
const (
|
||||
AttrString AttrType = iota // Single-value string
|
||||
AttrStringMulti // Multi-value string
|
||||
AttrInt // Integer (stored as string in LDAP)
|
||||
AttrBool // Boolean (TRUE/FALSE in LDAP)
|
||||
AttrDN // DN single
|
||||
AttrDNMulti // DN multi
|
||||
AttrTime // GeneralizedTime
|
||||
)
|
||||
|
||||
// AttrDef defines an LDAP attribute with its JSON mapping and type info
|
||||
type AttrDef struct {
|
||||
LDAPName string // LDAP attribute name (e.g. "gscMailEnabled")
|
||||
JSONName string // JSON field name (e.g. "enabled")
|
||||
Type AttrType // Value type for conversion
|
||||
Domain string // Service domain (e.g. "mail", "calendar")
|
||||
ReadOnly bool // If true, not settable via API
|
||||
}
|
||||
|
||||
// ObjectClassDef defines an LDAP objectClass
|
||||
type ObjectClassDef struct {
|
||||
Name string // ObjectClass name (e.g. "gscMailUser")
|
||||
Kind string // "AUXILIARY" or "STRUCTURAL"
|
||||
Must []string // Required LDAP attributes
|
||||
May []string // Optional LDAP attributes
|
||||
Domain string // Service domain this OC belongs to
|
||||
}
|
||||
|
||||
// EntityTypeDef defines a standalone LDAP entity type for CRUD operations
|
||||
type EntityTypeDef struct {
|
||||
Name string // URL-safe name (e.g. "tenant", "dlp-policy")
|
||||
Description string // Human-readable description
|
||||
ObjectClasses []string // Required objectClasses
|
||||
BaseDN string // Relative base DN (appended to LDAP base)
|
||||
RDNAttribute string // Attribute used as RDN (e.g. "cn", "gscTenantId")
|
||||
SearchFilter string // LDAP search filter for listing
|
||||
Domain string // Logical domain grouping
|
||||
RequiredAttrs []string // Attributes required on create
|
||||
}
|
||||
Reference in New Issue
Block a user