ThatAIguyA world of ideas

THE CONSCIOUSNESS ATLAS
Read. Experiment. Follow the evidence.

ConsciousnessLearn · Explore · Joseph Anady

Janady13/missionmatch / internal/platform/orgsettings/settings.go

Source identity, revision, and recovered contents.

GitHub sourceSource text recovered

Source identity

FieldRecorded value
Source typeGitHub source
Original recordJanady13/missionmatch / internal/platform/orgsettings/settings.go
DateNot specified in source
RepositoryJanady13/missionmatch
Revision720d47fae476b0d38477ae4401697d372b1ea2bc
Branchfeature/opportunity-to-outcome
Path or archive memberinternal/platform/orgsettings/settings.go
Original SHA-2565a8e6b808f98c90b4e2f4bd5000384aaae5be257503e0c425445eec1b41da582
Git blob SHA08ae1cb74aa9cdffe591028294cf30af4b2329ad
Reading-copy SHA-25662b3d250af3aebd4b4e5fdfa193111a60a01fa90e4c948d74182d008343e18e8

Original source ↗

Recovered source transcript

Credential-bearing and unrelated personal details were removed from this reading copy. The source identity and original checksum remain recorded.

// Package orgsettings holds the per organization configuration and the per organization sealed secrets. // // IT IS A PLATFORM PACKAGE, not a module, because three unrelated callers need it and none of them should // depend on each other. The org module serves the settings screen. The auth module needs the mail // configuration to deliver an invite. The recruiting module needs the visibility rules to decide whether one // recruiter may see another's work. If this lived inside any one of those, the other two would import a // sibling module, which is exactly the dependency the package layout rule exists to prevent. // // SECRETS NEVER LEAVE THIS PACKAGE AS PLAINTEXT BY ACCIDENT. Settings and secrets are deliberately separate // types with separate loaders: Load returns configuration a handler may serialise straight to JSON and it // CANNOT carry a credential, because no field of it holds one. Reaching a password takes a second, explicit // call to OpenSecret, which no HTTP response path calls. The type system carries the rule so a future handler // cannot leak a password by adding a field to a response struct. package orgsettings import ( "context" "errors" "fmt" "strings" "github.com/shopspring/decimal" "time" "github.com/google/uuid" "github.com/jackc/pgx/v5" "github.com/missionworkforce/missionmatch/internal/platform/security" "github.com/missionworkforce/missionmatch/internal/platform/tenant" ) // ErrNoSecret means the named secret is not stored for this organization. It is a normal outcome, not a // fault: an organization that has never configured mail simply has no smtp_password. var ErrNoSecret = errors.New("orgsettings: no such secret for this organization") // ErrSealUnavailable means the server has no organization secret key configured, so a secret cannot be // stored. It FAILS CLOSED and says so plainly rather than storing anything unprotected. A node without the // key can still read every non secret setting; only writing a credential is refused. var ErrSealUnavailable = errors.New("orgsettings: secret storage is not configured on this node, MM_ORG_SECRET_KEK is unset") // Settings is one organization's configuration. Every field here is safe to return to a caller who holds // org.settings.write. NONE of them is a credential. type Settings struct { // ---- outbound email ---- EmailDeliveryEnabled bool `json:"email_delivery_enabled"` EmailFromAddress string `json:"email_from_address"` EmailFromName string `json:"email_from_name"` EmailReplyTo string `json:"email_reply_to"` SMTPHost string `json:"smtp_host"` SMTPPort int `json:"smtp_port"` SMTPUsername string `json:"smtp_username"` SMTPSecurity string `json:"smtp_security"` // SMTPPasswordSet reports only WHETHER a password is [credential removed], never anything about it. This is what lets // the settings screen render "password saved, leave blank to keep it" without the value ever being sent // to a browser. SMTPPasswordSet bool `json:"smtp_password_set"` SMTPVerifiedAt *time.Time `json:"smtp_verified_at"` SMTPLastAttemptAt *time.Time `json:"smtp_last_attempt_at"` SMTPLastError string `json:"smtp_last_error"` // ---- visibility ---- WorkVisibility security.WorkVisibility `json:"work_visibility"` ShowActivityPresence bool `json:"show_activity_presence"` ClaimRequired bool `json:"claim_required"` ClaimExpiryHours int `json:"claim_expiry_hours"` // ---- field sensitivity ---- RateVisibility security.Sensitivity `json:"rate_visibility"` MarginVisibility security.Sensitivity `json:"margin_visibility"` ContactVisibility security.Sensitivity `json:"contact_visibility"` // ---- record scope, the third access axis ---- StaffRecordScope security.RecordScope `json:"staff_record_scope"` ManagerRecordScope security.RecordScope `json:"manager_record_scope"` UnownedRecordsVisible bool `json:"unowned_records_visible"` // ---- operating defaults ---- InviteExpiryHours int `json:"invite_expiry_hours"` DefaultInviteRole string `json:"default_invite_role"` // DefaultBurdenPct is the organization's standard wrap rate, as a FRACTION, so 0.35 is a 35 percent wrap. // It is the cost of employing somebody on top of their pay: payroll taxes, workers compensation, // unemployment insurance, health cover, paid leave, retirement, general and administrative, overhead. // // NIL IS THE SHIPPED STATE AND IS NOT A ZERO. Nil means the firm has not told us its wrap, and per clause A // of migration 0086 no margin may then be reported anywhere: the product shows spreads and says why. A wrap // of zero is a different and legitimate answer, and it produces a margin equal to the spread. Collapsing // the two would invent a cost structure for every organization that has not entered one. // // It is a STRING on the wire, in the decimal discipline the rest of the money follows, because a wrap that // round tripped through a JSON number is a float and a float does not reconcile with an invoice. DefaultBurdenPct *decimal.Decimal `json:"default_burden_pct,omitempty"` // AEDTNoticeRequired refuses to score a candidate who has no automated decision notice on file. // // OFF BY DEFAULT, and the migration records why: switching it on for an existing customer would refuse // their whole bench the moment they upgraded, because nobody has notices yet. What ships on for everybody // is the ability to record a notice and to see whether one exists; the enforcement is the owner's call // once their notices are in place. AEDTNoticeRequired bool `json:"aedt_notice_required"` UpdatedAt time.Time `json:"updated_at"` } // Defaults returns the same values the migration writes. It exists so a read against an organization whose // row is somehow missing returns a SAFE configuration rather than a zero valued one. The distinction matters: // the zero value of WorkVisibility is the empty string, which CanSeeOthersWork denies, but the zero value of // EmailDeliveryEnabled is false and the zero value of ClaimExpiryHours is zero, which would expire every // claim the instant it was made. Defaults are the correct answer, zeroes are not. func Defaults() Settings { return Settings{ SMTPSecurity: "starttls", WorkVisibility: security.VisibilityOrganization, ShowActivityPresence: true, ClaimRequired: false, ClaimExpiryHours: 72, StaffRecordScope: security.ScopeOrganization, ManagerRecordScope: security.ScopeOrganization, UnownedRecordsVisible: true, RateVisibility: security.SensitivityManagers, MarginVisibility: security.SensitivityOwner, ContactVisibility: security.SensitivityTeam, InviteExpiryHours: 72, DefaultInviteRole: string(security.RoleRecruiter), } } // Store reads and writes settings and secrets inside the caller's tenant transaction, so RLS decides which // organization is reachable and this package never names one. There is no organization_id parameter anywhere // in this file, deliberately: a function that took one could be called with the wrong one. type Store struct { db *tenant.DB kek []byte // prev decrypts values sealed under the previous key so a rotation does not need a flag day. It is used // only on the read path, never to seal anything new. prev []byte kekVersion int } func NewStore(db *tenant.DB, kek, prev []byte, kekVersion int) *Store { return &Store{db: db, kek: kek, prev: prev, kekVersion: kekVersion} } // SealAvailable reports whether this node can store a secret. Callers use it to give an honest error before // asking a user to type a password they cannot save. func (s *Store) SealAvailable() bool { return len(s.kek) == security.AESKeySize } const settingsColumns = ` email_delivery_enabled, coalesce(email_from_address,''), coalesce(email_from_name,''), coalesce(email_reply_to,''), coalesce(smtp_host,''), coalesce(smtp_port,0), coalesce(smtp_username,''), smtp_security, smtp_verified_at, smtp_last_attempt_at, coalesce(smtp_last_error,''), work_visibility, show_activity_presence, claim_required, claim_expiry_hours, rate_visibility, margin_visibility, contact_visibility, staff_record_scope, manager_record_scope, unowned_records_visible, invite_expiry_hours, default_invite_role, default_burden_pct::text, aedt_notice_required, updated_at` func scanSettings(row pgx.Row) (Settings, error) { var st Settings var burden *string err := row.Scan( &st.EmailDeliveryEnabled, &st.EmailFromAddress, &st.EmailFromName, &st.EmailReplyTo, &st.SMTPHost, &st.SMTPPort, &st.SMTPUsername, &st.SMTPSecurity, &st.SMTPVerifiedAt, &st.SMTPLastAttemptAt, &st.SMTPLastError, &st.WorkVisibility, &st.ShowActivityPresence, &st.ClaimRequired, &st.ClaimExpiryHours, &st.RateVisibility, &st.MarginVisibility, &st.ContactVisibility, &st.StaffRecordScope, &st.ManagerRecordScope, &st.UnownedRecordsVisible, &st.InviteExpiryHours, &st.DefaultInviteRole, &burden, &st.AEDTNoticeRequired, &st.UpdatedAt, ) if err == nil && burden != nil { // Parsed rather than trusted. A value that reached the column can only have come through the CHECK, so // a parse failure here would mean the column type changed under us, and a silently dropped wrap would // turn every margin in the product into a spread again without saying so. d, perr := decimal.NewFromString(*burden) if perr != nil { return Settings{}, fmt.Errorf("orgsettings: default_burden_pct %q is not a number: %w", *burden, perr) } st.DefaultBurdenPct = &d } return st, err } // LoadTx reads the settings for the tenant already established on tx. A missing row returns Defaults with no // error, because an organization created before this migration, or one whose backfill has not run, should // behave like a correctly configured new organization rather than fail. func (s *Store) LoadTx(ctx context.Context, tx pgx.Tx) (Settings, error) { st, err := scanSettings(tx.QueryRow(ctx, `SELECT `+settingsColumns+` FROM org_settings`)) if errors.Is(err, pgx.ErrNoRows) { return Defaults(), nil } if err != nil { return Settings{}, fmt.Errorf("orgsettings: load: %w", err) } var n int if err := tx.QueryRow(ctx, `SELECT count(*)::int FROM org_secrets WHERE name = 'smtp_password'`).Scan(&n); err != nil { return Settings{}, fmt.Errorf("orgsettings: probe smtp password: %w", err) } st.SMTPPasswordSet = n > 0 return st, nil } // Load opens its own tenant transaction for callers that are not already inside one. func (s *Store) Load(ctx context.Context) (Settings, error) { var out Settings err := s.db.RunInTenantTx(ctx, func(ctx context.Context, tx pgx.Tx) error { var e error out, e = s.LoadTx(ctx, tx) return e }) return out, err } // Update is a sparse patch: only the fields a caller actually set are written. A pointer per field rather // than a whole Settings value, because a settings screen that submits the entire object would silently // overwrite a colleague's concurrent change to a field the submitter never touched. type Update struct { EmailDeliveryEnabled *bool EmailFromAddress *string EmailFromName *string EmailReplyTo *string SMTPHost *string SMTPPort *int SMTPUsername *string SMTPSecurity *string WorkVisibility *string ShowActivityPresence *bool ClaimRequired *bool ClaimExpiryHours *int RateVisibility *string MarginVisibility *string ContactVisibility *string StaffRecordScope *string ManagerRecordScope *string UnownedRecordsVisible *bool InviteExpiryHours *int DefaultInviteRole *string // DefaultBurdenPct is a POINTER TO A POINTER on purpose, which is the only shape that can express the three // things an owner can mean. Absent, the outer nil, means leave the wrap alone. Present and pointing at nil // means CLEAR it, which returns the organization to reporting spreads and no margins. Present and pointing // at a number sets it. A plain pointer could not tell "do not touch" apart from "clear", and clearing a // wrap by accident silently changes every margin in the product to a different number. DefaultBurdenPct **decimal.Decimal AEDTNoticeRequired *bool } // maxBurden is five, meaning a wrap of five hundred percent, matching the CHECK migration 0098 puts on every // burden column. It is high enough to admit a genuinely heavy government wrap once general and administrative // and fee are layered on, and low enough to catch the one error that would otherwise pass silently: typing 35 // to mean 35 percent. var maxBurden = decimal.NewFromInt(5) // Validate checks everything the database checks, plus the things it cannot: that a time zone actually // exists, that a role is a real role, that an address looks like an address. Returning the offending field // name lets the settings screen mark the input rather than show a banner. func (u Update) Validate() (field string, err error) { if u.DefaultBurdenPct != nil && *u.DefaultBurdenPct != nil { b := **u.DefaultBurdenPct if b.IsNegative() { return "default_burden_pct", errors.New("a wrap rate cannot be negative") } if b.GreaterThan(maxBurden) { // The message names the likely mistake rather than restating the bound, because somebody who typed // 35 does not need to be told the limit is 5, they need to be told the field is a fraction. return "default_burden_pct", errors.New( "a wrap rate is a fraction, so a 35 percent wrap is 0.35 rather than 35") } } if u.SMTPPort != nil && (*u.SMTPPort < 1 || *u.SMTPPort > 65535) { return "smtp_port", errors.New("a port must be between 1 and 65535") } if u.SMTPSecurity != nil && *u.SMTPSecurity != "starttls" && *u.SMTPSecurity != "implicit_tls" { return "smtp_security", errors.New("transport security must be starttls or implicit_tls, plaintext mail is not offered") } for f, v := range map[string]*string{ "email_from_address": u.EmailFromAddress, "email_reply_to": u.EmailReplyTo, } { if v != nil && *v != "" && !plausibleAddress(*v) { return f, errors.New("that does not look like an email address") } } if u.WorkVisibility != nil && !security.ValidWorkVisibility(security.WorkVisibility(*u.WorkVisibility)) { return "work_visibility", errors.New("visibility must be private, team or organization") } for f, v := range map[string]*string{ "rate_visibility": u.RateVisibility, "margin_visibility": u.MarginVisibility, "contact_visibility": u.ContactVisibility, } { if v != nil && !security.ValidSensitivity(security.Sensitivity(*v)) { return f, errors.New("sensitivity must be owner, managers, team or organization") } } if u.StaffRecordScope != nil && !security.ValidRecordScope(security.RecordScope(*u.StaffRecordScope)) { return "staff_record_scope", errors.New("a record scope must be own, team or organization") } // own is deliberately not offered at the manager tier: a manager who cannot see their team's records // cannot run a desk, and the setting exists to choose between the team and the floor. if u.ManagerRecordScope != nil && !security.ValidManagerScope(security.RecordScope(*u.ManagerRecordScope)) { return "manager_record_scope", errors.New("a manager may be scoped to team or organization, not to their own records alone") } if u.ClaimExpiryHours != nil && (*u.ClaimExpiryHours < 1 || *u.ClaimExpiryHours > 2160) { return "claim_expiry_hours", errors.New("a claim may last between one hour and ninety days") } if u.InviteExpiryHours != nil && (*u.InviteExpiryHours < 1 || *u.InviteExpiryHours > 336) { return "invite_expiry_hours", errors.New("an invite may last between one hour and fourteen days") } if u.DefaultInviteRole != nil { r := security.Role(*u.DefaultInviteRole) if !security.ValidRole(r) || r == security.RoleOwner { return "default_invite_role", errors.New("the default invited role must be a real role below owner") } } return "", nil } // invalidatesVerification reports whether a patch changes anything that a previous successful test send // proved. Changing the host, port, username, security or sender means the old proof no longer describes the // current configuration, so verification is cleared and mail stops until somebody tests again. // // THIS IS THE HONEST BEHAVIOUR AND IT IS DELIBERATELY INCONVENIENT. The alternative, leaving the old // verified_at in place, means an admin edits a host name, saves, and the platform silently keeps claiming // mail works until the first invite disappears into nothing. func (u Update) invalidatesVerification() bool { return u.SMTPHost != nil || u.SMTPPort != nil || u.SMTPUsername != nil || u.SMTPSecurity != nil || u.EmailFromAddress != nil } // Save applies a sparse patch inside tx. It returns the settings as they now stand. func (s *Store) Save(ctx context.Context, tx pgx.Tx, u Update, actor uuid.UUID) (Settings, error) { set := make([]string, 0, 20) args := make([]any, 0, 20) add := func(col string, v any) { args = append(args, v) set = append(set, fmt.Sprintf("%s = $%d", col, len(args))) } if u.EmailDeliveryEnabled != nil { add("email_delivery_enabled", *u.EmailDeliveryEnabled) } if u.EmailFromAddress != nil { add("email_from_address", nilIfEmpty(*u.EmailFromAddress)) } if u.EmailFromName != nil { add("email_from_name", nilIfEmpty(*u.EmailFromName)) } if u.EmailReplyTo != nil { add("email_reply_to", nilIfEmpty(*u.EmailReplyTo)) } if u.SMTPHost != nil { add("smtp_host", nilIfEmpty(strings.TrimSpace(*u.SMTPHost))) } if u.SMTPPort != nil { add("smtp_port", *u.SMTPPort) } if u.SMTPUsername != nil { add("smtp_username", nilIfEmpty(*u.SMTPUsername)) } if u.SMTPSecurity != nil { add("smtp_security", *u.SMTPSecurity) } if u.WorkVisibility != nil { add("work_visibility", *u.WorkVisibility) } if u.ShowActivityPresence != nil { add("show_activity_presence", *u.ShowActivityPresence) } if u.ClaimRequired != nil { add("claim_required", *u.ClaimRequired) } if u.ClaimExpiryHours != nil { add("claim_expiry_hours", *u.ClaimExpiryHours) } if u.RateVisibility != nil { add("rate_visibility", *u.RateVisibility) } if u.MarginVisibility != nil { add("margin_visibility", *u.MarginVisibility) } if u.ContactVisibility != nil { add("contact_visibility", *u.ContactVisibility) } if u.StaffRecordScope != nil { add("staff_record_scope", *u.StaffRecordScope) } if u.ManagerRecordScope != nil { add("manager_record_scope", *u.ManagerRecordScope) } if u.UnownedRecordsVisible != nil { add("unowned_records_visible", *u.UnownedRecordsVisible) } if u.InviteExpiryHours != nil { add("invite_expiry_hours", *u.InviteExpiryHours) } if u.DefaultInviteRole != nil { add("default_invite_role", *u.DefaultInviteRole) } if u.AEDTNoticeRequired != nil { add("aedt_notice_required", *u.AEDTNoticeRequired) } if u.DefaultBurdenPct != nil { // The inner nil is a deliberate CLEAR, written as a NULL, not skipped. An owner who removes their wrap // is telling the product it no longer knows their cost structure, and the honest consequence is that // every margin disappears and every spread stays. if *u.DefaultBurdenPct == nil { add("default_burden_pct", nil) } else { add("default_burden_pct", (*u.DefaultBurdenPct).String()) } } if u.invalidatesVerification() { set = append(set, "smtp_verified_at = NULL") // Delivery is switched off at the same moment, because the CHECK constraint refuses a row that has // delivery enabled with no verification, and because an admin editing a host mid flight should not // have invites silently queue against a configuration nobody has proved. set = append(set, "email_delivery_enabled = false") } if len(set) == 0 { return s.LoadTx(ctx, tx) } add("updated_by", actor) set = append(set, "updated_at = now()") // The row is guaranteed FIRST, then updated. This was written as a single INSERT ... ON CONFLICT DO // UPDATE, which is wrong in a way that passed every review and failed the first walkthrough: an // organization with no row yet took the INSERT branch, where the SET clause does not apply, so the very // first save an owner performed reported 200 and changed nothing. provision_org does not create a // settings row, so EVERY newly provisioned customer hit it. Two statements, no cleverness. if err := s.ensureRow(ctx, tx); err != nil { return Settings{}, err } if _, err := tx.Exec(ctx, `UPDATE org_settings SET `+strings.Join(set, ", "), args...); err != nil { return Settings{}, fmt.Errorf("orgsettings: save: %w", err) } return s.LoadTx(ctx, tx) } // ensureRow creates this organization's settings row if it does not have one, so every writer below can be a // plain UPDATE. An UPDATE against a missing row affects zero rows and reports success, which is the failure // mode this exists to remove. func (s *Store) ensureRow(ctx context.Context, tx pgx.Tx) error { _, err := tx.Exec(ctx, ` INSERT INTO org_settings (organization_id) VALUES (NULLIF(current_setting('app.current_org_id', true), '')::uuid) ON CONFLICT (organization_id) DO NOTHING`) if err != nil { return fmt.Errorf("orgsettings: ensure settings row: %w", err) } return nil } // MarkVerified records that a test send actually succeeded. It is the ONLY writer of smtp_verified_at, which // is what makes that column mean what it says. func (s *Store) MarkVerified(ctx context.Context, tx pgx.Tx) error { if err := s.ensureRow(ctx, tx); err != nil { return err } _, err := tx.Exec(ctx, `UPDATE org_settings SET smtp_verified_at = now(), smtp_last_attempt_at = now(), smtp_last_error = NULL, updated_at = now()`) return err } // MarkAttemptFailed records a failed send with the transport's own message, so an admin can fix a typo // without reading a server log they have no access to. // // THE MESSAGE IS SCRUBBED FIRST. A transport error can echo the credentials it was rejecting, and this column // is readable by anyone holding org.settings.write and is returned over the API. redactCredentials removes // the username and password from the text before it is stored, so the worst case is a less useful error // rather than a password sitting in a readable column. func (s *Store) MarkAttemptFailed(ctx context.Context, tx pgx.Tx, cause string, username, password string) error { msg := redactCredentials(cause, username, password) if len(msg) > 500 { msg = msg[:500] } if err := s.ensureRow(ctx, tx); err != nil { return err } _, err := tx.Exec(ctx, `UPDATE org_settings SET smtp_verified_at = NULL, email_delivery_enabled = false, smtp_last_attempt_at = now(), smtp_last_error = $1, updated_at = now()`, msg) return err } func redactCredentials(s, username, password string) string { for _, secret := range []string{password, username} { // Short values are skipped: redacting a two character username would replace half the alphabet in the // message and tell the reader nothing. if len(secret) >= 4 { s = strings.ReplaceAll(s, secret, "[redacted]") } } return s } func nilIfEmpty(s string) any { if strings.TrimSpace(s) == "" { return nil } return s } // plausibleAddress is a deliberately loose check. Address syntax is far wider than most validators admit, and // rejecting a valid address is a worse failure than accepting an invalid one that simply bounces. It catches // the actual mistakes: a name with no address, spaces, a missing at sign, a missing dot in the domain. func plausibleAddress(v string) bool { v = strings.TrimSpace(v) if len(v) < 6 || len(v) > 320 || strings.ContainsAny(v, " \t\r\n<>,;") { return false } at := strings.LastIndexByte(v, '@') if at <= 0 || at == len(v)-1 { return false } domain := v[at+1:] dot := strings.IndexByte(domain, '.') return dot > 0 && dot < len(domain)-1 }

Search equations, builds, manuscript text, and recovered sources.