Documentation
¶
Overview ¶
Package organization provides optional PostgreSQL/SQLite tenant membership and session context.
Index ¶
- Constants
- func Contract() plugin.Definition
- func DeprovisionMember(tx storage.Tx, id, userID string) error
- func PruneExpired(ctx context.Context, store storage.Store, before time.Time, limit int) (int64, error)
- type Invitation
- type IssuedInvitation
- type Membership
- type Organization
- type Permission
- type Plugin
- func (p *Plugin) AcceptInvitation(ctx context.Context, id string, token sigil.Secret) (Tenant, error)
- func (p *Plugin) Active(ctx context.Context) (Tenant, error)
- func (p *Plugin) Bind(a *sigil.Auth) error
- func (p *Plugin) ChangeRole(ctx context.Context, id, userID string, role Role) (Tenant, error)
- func (p *Plugin) Create(ctx context.Context, name string) (Tenant, error)
- func (p *Plugin) Definition() plugin.Definition
- func (p *Plugin) Get(ctx context.Context, id string) (Tenant, error)
- func (p *Plugin) Invite(ctx context.Context, id, email string) (IssuedInvitation, error)
- func (p *Plugin) RemoveMember(ctx context.Context, id, userID string) error
- func (p *Plugin) Rename(ctx context.Context, id, name string) (Tenant, error)
- func (p *Plugin) RevokeInvitation(ctx context.Context, id, invitationID string) error
- func (p *Plugin) SetActive(ctx context.Context, id string) (Tenant, error)
- func (p *Plugin) TransferOwnership(ctx context.Context, id, userID string) (Tenant, error)
- func (p *Plugin) WithActive(ctx context.Context, op plugin.Operation, fn func(storage.Tx, Tenant) error) error
- func (p *Plugin) WithPermission(ctx context.Context, id string, permission Permission, op plugin.Operation, ...) error
- func (p *Plugin) WithTenant(ctx context.Context, id string, op plugin.Operation, ...) error
- type Role
- type Tenant
Constants ¶
const ( InviteOperation plugin.Operation = "organization.invite" AcceptOperation plugin.Operation = "organization.accept" RevokeInvitationOperation plugin.Operation = "organization.invitation.revoke" RemoveMemberOperation plugin.Operation = "organization.member.remove" TransferOwnershipOperation plugin.Operation = "organization.ownership.transfer" InvitationLifetime = 24 * time.Hour )
const CreateOperation plugin.Operation = "organization.create"
const ID = "organization"
const RenameOperation plugin.Operation = "organization.rename"
const SelectOperation plugin.Operation = "organization.select"
Variables ¶
This section is empty.
Functions ¶
func Contract ¶
func Contract() plugin.Definition
func DeprovisionMember ¶
DeprovisionMember removes userID's membership of organization id inside a trusted transaction that already holds that user's core lock. It is for plugins that remove members on the organization's behalf, such as SCIM deprovisioning. The owner is never removed (sigil.ErrForbidden): ownership must be transferred first. Removing a non-member succeeds without change. Like an administrative RemoveMember, it withdraws the organization's outstanding invitations, which may be addressed to the account's former email identities, and active selections cascade.
Types ¶
type Invitation ¶
type Invitation struct {
ID string `json:"id"`
OrganizationID string `json:"organizationId"`
Email string `json:"email"`
ExpiresAt time.Time `json:"expiresAt"`
}
Invitation contains public metadata. IssuedInvitation.Token is returned only after commit; the host delivers it to Email without logging or URL analytics.
type IssuedInvitation ¶
type IssuedInvitation struct {
Invitation Invitation `json:"invitation"`
Token sigil.Secret `json:"-"`
}
type Membership ¶
type Organization ¶
type Permission ¶
type Permission string
Permission names the library's organization actions, not arbitrary application resources.
const ( PermissionRead Permission = "read" PermissionRename Permission = "rename" PermissionInvite Permission = "invite" PermissionRevokeInvitation Permission = "invitation.revoke" PermissionRemoveMember Permission = "member.remove" PermissionChangeRole Permission = "member.role.change" PermissionTransferOwnership Permission = "ownership.transfer" // PermissionManageAPIKeys issues and uses organization-bound API keys. PermissionManageAPIKeys Permission = "api_key.manage" // PermissionManageSSO configures the organization's SSO connections and // verified domains. It is owner-only: a connection decides which identity // provider can sign members in. PermissionManageSSO Permission = "sso.manage" ChangeRoleOperation plugin.Operation = "organization.member.role.change" )
type Plugin ¶
type Plugin struct {
// contains filtered or unexported fields
}
func (*Plugin) AcceptInvitation ¶
func (p *Plugin) AcceptInvitation(ctx context.Context, id string, token sigil.Secret) (Tenant, error)
AcceptInvitation requires the authenticated account's current verified email. Consumption and membership insertion commit together. Existing members retain their role; acceptance never promotes a member or downgrades an owner.
func (*Plugin) ChangeRole ¶
ChangeRole changes an existing non-owner to member or admin. Only the live owner can do so; ownership changes must use TransferOwnership. The returned tenant describes the target. Existing sessions observe the role on next use.
func (*Plugin) Create ¶
Create atomically creates an organization and the caller's owner membership.
func (*Plugin) Definition ¶
func (p *Plugin) Definition() plugin.Definition
func (*Plugin) Invite ¶
Invite issues a member invitation bound to a canonical email and tenant. Reissuing for the same tenant/email invalidates every earlier invitation.
func (*Plugin) RemoveMember ¶
RemoveMember permits owners to remove non-owners, admins to remove regular members, and any non-owner to leave. The sole owner must transfer first. Cascades clear every active selection.
func (*Plugin) RevokeInvitation ¶
func (*Plugin) TransferOwnership ¶
TransferOwnership atomically promotes an existing member and demotes the caller. Exactly one owner exists at commit. Outstanding invitations are revoked so authority granted by the former owner does not survive transfer.
func (*Plugin) WithActive ¶
func (p *Plugin) WithActive(ctx context.Context, op plugin.Operation, fn func(storage.Tx, Tenant) error) error
WithActive resolves the session selection and rechecks membership on every call. A missing selection (including removal) fails closed with forbidden.
func (*Plugin) WithPermission ¶
func (p *Plugin) WithPermission(ctx context.Context, id string, permission Permission, op plugin.Operation, fn func(storage.Tx, Tenant) error) error
WithPermission checks a live role and session and holds tenant locks through the callback commit. Administrative permissions require recent sensitive assurance. The host must still bind application resources to this tenant.
func (*Plugin) WithTenant ¶
func (p *Plugin) WithTenant(ctx context.Context, id string, op plugin.Operation, fn func(storage.Tx, Tenant) error) error
WithTenant authorizes live membership and runs trusted application work in the same transaction. Always scope resource queries to tenant.Organization.ID. Never retain tx or use this snapshot as a later authorization decision.
type Role ¶
type Role string
Role is a closed organization role. Unknown roles grant no permissions.
func (Role) Allows ¶
func (r Role) Allows(p Permission) bool
Allows evaluates the role matrix only. It does not authenticate a caller or establish freshness. Use WithPermission for an atomic authorization decision. Removal additionally restricts the target: admins may remove only members.
type Tenant ¶
type Tenant struct {
Organization Organization `json:"organization"`
Membership Membership `json:"membership"`
}
func LiveMembership ¶
LiveMembership reads userID's live membership inside a trusted transaction that already holds that user's core lock, for plugins that bind their own credentials to a tenant. It holds share locks on the organization and membership through commit, so concurrent removal or role changes wait. A missing organization or membership is sigil.ErrForbidden.
func ProvisionMember ¶
ProvisionMember gives userID a member role in organization id unless it already has a membership, whose role is then kept, inside a trusted transaction that already holds that user's core lock. It is for plugins that admit members on the organization's behalf, such as SSO just-in-time membership; it never promotes, and it locks the organization like other lifecycle decisions. A missing organization is sigil.ErrForbidden.