ThatAIguyA world of ideas

THE CONSCIOUSNESS ATLAS
Read. Experiment. Follow the evidence.

ConsciousnessLearn · Explore · Joseph Anady

Janady13/missionmatch / internal/modules/platform/organizations.go

Source identity, revision, and recovered contents.

GitHub sourceSource text recovered

Source identity

FieldRecorded value
Source typeGitHub source
Original recordJanady13/missionmatch / internal/modules/platform/organizations.go
DateNot specified in source
RepositoryJanady13/missionmatch
Revision720d47fae476b0d38477ae4401697d372b1ea2bc
Branchfeature/opportunity-to-outcome
Path or archive memberinternal/modules/platform/organizations.go
Original SHA-2566a795a682a1997d7098e53a93503179546db33df90b08902490591fa8dae9639
Git blob SHA7b786c661d0efd31bacd75d0e5ca77004aa8f4b8
Reading-copy SHA-2566a795a682a1997d7098e53a93503179546db33df90b08902490591fa8dae9639

Original source ↗

Recovered source transcript

// Package platform is the OPERATOR PLANE: cross tenant surfaces that belong to whoever runs the platform // rather than to any customer inside it. Everything here mounts inside the RequirePlatform group in // cmd/api/main.go and inherits that gate rather than remembering it individually, which is what the comment // there asks for. // // WHY THIS EXISTS. Creating a customer required SSH to a production server and running cmd/provision-org. // Loading their bench required cmd/import-candidates. So onboarding, the single thing that has to happen // before anyone can use this product at all, was the one thing the product could not do. The engineering was // well ahead of the operations, and this is the first piece of closing that gap. // // IT DOES NOT WEAKEN THE PROVISIONING DESIGN, and that distinction is the whole point. org creation stays a // SECURITY DEFINER function that the APP ROLE CANNOT EXECUTE: missionmatch_app has no INSERT on organizations // and no EXECUTE on provision_org, deliberately, so a compromised application session cannot mint a tenant. // This handler reaches provision_org through the MIGRATOR POOL, the same BYPASSRLS seam curation_apply // already uses for migrator owned tables, and that pool fails closed at boot unless it really is the migrator // role. So the privilege boundary is unchanged; only the operator's path to it is. package platform import ( "context" "encoding/json" "net/http" "strings" "time" "github.com/go-chi/chi/v5" "github.com/google/uuid" "github.com/jackc/pgx/v5/pgxpool" "github.com/missionworkforce/missionmatch/internal/platform/audit" "github.com/missionworkforce/missionmatch/internal/platform/security" "github.com/missionworkforce/missionmatch/internal/platform/tenant" ) // Handler serves the operator plane. migrator may be nil, in which case provisioning reports itself // unavailable rather than pretending: an operator console that silently does nothing is worse than one that // says the migrator DSN is not configured on this node. type Handler struct { migrator *pgxpool.Pool aud *audit.Writer } func NewHandler(migrator *pgxpool.Pool, aud *audit.Writer) *Handler { return &Handler{migrator: migrator, aud: aud} } func (h *Handler) Routes(r chi.Router) { r.Get("/platform/organizations", h.listOrganizations) r.Post("/platform/organizations", h.createOrganization) } type createOrgRequest struct { Name string `json:"name"` Slug string `json:"slug"` OwnerEmail string `json:"owner_email"` OwnerName string `json:"owner_name"` ExpiryHours int `json:"expiry_hours"` } // createOrgResponse carries the activation token EXACTLY ONCE. Only its hash is stored, so this response is // the only moment the plaintext exists anywhere, and it is never logged, never audited, and never retrievable // afterwards. An operator who loses it issues a new invite rather than reading the old one back. type createOrgResponse struct { OrganizationID string `json:"organization_id"` OwnerUserID string `json:"owner_user_id"` InviteID string `json:"invite_id"` ActivationToken string `json:"activation_token"` ExpiresAt string `json:"expires_at"` RedeemAt string `json:"redeem_at"` Note string `json:"note"` } const maxExpiryHours = 24 * 14 func (h *Handler) createOrganization(w http.ResponseWriter, r *http.Request) { if h.migrator == nil { writeErr(w, http.StatusServiceUnavailable, "provisioning is unavailable on this node because no migrator DSN is configured") return } var in createOrgRequest if err := json.NewDecoder(http.MaxBytesReader(w, r.Body, 8<<10)).Decode(&in); err != nil { writeErr(w, http.StatusBadRequest, "invalid body") return } in.Name = strings.TrimSpace(in.Name) in.Slug = strings.ToLower(strings.TrimSpace(in.Slug)) in.OwnerEmail = strings.ToLower(strings.TrimSpace(in.OwnerEmail)) in.OwnerName = strings.TrimSpace(in.OwnerName) // Validated HERE rather than only at the database, so the operator gets a sentence instead of a constraint // violation. The database still enforces all of it, because a check that lives only in a handler is a // check a second caller skips. switch { case in.Name == "": writeField(w, "name", "an organization name is required") return case in.Slug == "": writeField(w, "slug", "a slug is required, it is the tenant's stable identifier") return case !validSlug(in.Slug): writeField(w, "slug", "a slug may hold only lowercase letters, digits and hyphens, and must start with a letter") return case in.OwnerEmail == "" || !strings.Contains(in.OwnerEmail, "@"): writeField(w, "owner_email", "a valid owner email is required, it becomes the first account") return case in.OwnerName == "": writeField(w, "owner_name", "an owner name is required") return } if in.ExpiryHours <= 0 { in.ExpiryHours = 72 } if in.ExpiryHours > maxExpiryHours { writeField(w, "expiry_hours", "an activation link may not live longer than fourteen days") return } // The token is generated by the SAME primitive the session layer uses, and only its HASH crosses into the // database. cmd/provision-org does exactly this; sharing the primitive rather than the code keeps one // definition of what a token is. token, tokenHash, err := security.NewSessionToken() if err != nil { writeErr(w, http.StatusInternalServerError, "could not generate an activation token") return } ctx, cancel := context.WithTimeout(r.Context(), 20*time.Second) defer cancel() var orgID, ownerID, inviteID uuid.UUID err = h.migrator.QueryRow(ctx, `SELECT organization_id, owner_user_id, invite_id FROM provision_org($1,$2,$3,$4,$5,$6)`, in.Name, in.Slug, in.OwnerEmail, in.OwnerName, tokenHash, in.ExpiryHours*3600, ).Scan(&orgID, &ownerID, &inviteID) if err != nil { // A duplicate slug or email is an operator mistake, not a server fault, and deserves a 409 with the // reason rather than a 500 that reads like an outage. msg := err.Error() if strings.Contains(msg, "duplicate key") || strings.Contains(msg, "unique constraint") { writeErr(w, http.StatusConflict, "that slug or owner email is already taken") return } writeErr(w, http.StatusInternalServerError, "provisioning failed") return } // AUDITED AS A PLATFORM EVENT with a NULL org, because creating a tenant is not an action inside any // tenant. THE TOKEN IS NOT IN THE AUDIT ROW. The audit records that an organization was created, by whom, // and for which owner email; recording the activation token would put a live credential in an append only // table that is deliberately impossible to delete from. if h.aud != nil { actor := actorID(r.Context()) body, _ := json.Marshal(map[string]any{ "organization_id": orgID.String(), "slug": in.Slug, "owner_user_id": ownerID.String(), "owner_email": in.OwnerEmail, "invite_id": inviteID.String(), "expiry_hours": in.ExpiryHours, }) _ = audit.OnPool(ctx, h.migrator, nil, audit.Event{ Action: "platform.organization.provisioned", ActorUserID: actor, EntityType: "organization", EntityID: orgID.String(), NewValues: body, IPAddress: r.Header.Get("X-Forwarded-For"), UserAgent: r.UserAgent(), }) } writeJSON(w, http.StatusCreated, createOrgResponse{ OrganizationID: orgID.String(), OwnerUserID: ownerID.String(), InviteID: inviteID.String(), ActivationToken: token, ExpiresAt: time.Now().UTC().Add(time.Duration(in.ExpiryHours) * time.Hour).Format(time.RFC3339), RedeemAt: "POST /api/auth/invite/accept", Note: "This token is shown ONCE and is not stored in plaintext anywhere. Deliver it to the owner, who " + "redeems it with a password of their choosing. The first owner receives their product tools " + "automatically. If the token is lost, provision a fresh invite rather than looking for this one.", }) } type orgRow struct { ID string `json:"id"` Name string `json:"name"` Slug string `json:"slug"` Status string `json:"status"` Users int `json:"users"` CreatedAt string `json:"created_at"` } // listOrganizations is a CROSS TENANT read and is why this whole surface is operator gated. It returns counts // and identifiers only: no candidate, no requirement, no document, nothing from inside a tenant. An operator // needs to see that a tenant exists and how many accounts it has, not what its customers are working on. func (h *Handler) listOrganizations(w http.ResponseWriter, r *http.Request) { if h.migrator == nil { writeErr(w, http.StatusServiceUnavailable, "the organization list is unavailable on this node because no migrator DSN is configured") return } ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second) defer cancel() rows, err := h.migrator.Query(ctx, ` SELECT o.id::text, o.name, o.slug, o.status, (SELECT count(*) FROM users u WHERE u.organization_id = o.id)::int, o.created_at FROM organizations o ORDER BY o.created_at DESC LIMIT 500`) if err != nil { writeErr(w, http.StatusInternalServerError, "could not list organizations") return } defer rows.Close() out := make([]orgRow, 0, 64) for rows.Next() { var o orgRow var created time.Time if err := rows.Scan(&o.ID, &o.Name, &o.Slug, &o.Status, &o.Users, &created); err != nil { writeErr(w, http.StatusInternalServerError, "could not read organizations") return } o.CreatedAt = created.UTC().Format(time.RFC3339) out = append(out, o) } if rows.Err() != nil { writeErr(w, http.StatusInternalServerError, "could not read organizations") return } writeJSON(w, http.StatusOK, map[string]any{"organizations": out, "count": len(out)}) } func validSlug(s string) bool { if len(s) < 2 || len(s) > 63 { return false } if s[0] < 'a' || s[0] > 'z' { return false } for _, c := range s { if (c < 'a' || c > 'z') && (c < '0' || c > '9') && c != '-' { return false } } return !strings.Contains(s, "--") } func actorID(ctx context.Context) *uuid.UUID { p, ok := tenant.UserFromContext(ctx) if !ok { return nil } id, err := uuid.Parse(p.UserID) if err != nil { return nil } return &id } func writeJSON(w http.ResponseWriter, status int, v any) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) _ = json.NewEncoder(w).Encode(v) } func writeErr(w http.ResponseWriter, status int, msg string) { writeJSON(w, status, map[string]string{"error": msg}) } func writeField(w http.ResponseWriter, field, msg string) { writeJSON(w, http.StatusUnprocessableEntity, map[string]string{"error": msg, "field": field}) }

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