Documentation
¶
Overview ¶
Package access is ContentKit's access model: the Actor; the key grammar (<tenant>:content:<id>, <tenant>:content:<id>/<version>, <tenant>:group:<id> and configured tiers); rules stored on content, versions and entities; the Gate deciding versions from one billing read per request, its listing Filter and SQL over content_facets; and the Billing dependency.
Index ¶
- Constants
- Variables
- func ChannelPermissions() []string
- func ChannelPrefix(tenant string) string
- func ContentPrefix(tenant string) string
- func Names(ps ...Permission) []string
- func ValidTenant(s string) bool
- type AccountMembership
- type Actor
- type Answer
- type Billing
- type Entitled
- type Facet
- type HeldKeys
- type Item
- type Key
- type KeyKind
- type Level
- type Mode
- type Permission
- type Preview
- type Query
- type Release
- type Rule
- func (r Rule) AudienceTiers(now time.Time) []string
- func (r Rule) Facet() Facet
- func (r Rule) Free(now time.Time) bool
- func (r Rule) Previewed(k kinds.Kind) Rule
- func (r *Rule) UnmarshalJSON(b []byte) error
- func (r Rule) Validate(cfg kinds.Config) error
- func (r Rule) ValidateReleases(cfg kinds.Config) error
- type TenureReader
Constants ¶
const Anyone = ""
Anyone is the audience of a free row: an anonymous visitor.
const (
// ChannelCommentsModerate permits moderating comments on the channel and its posts.
ChannelCommentsModerate = "channel:comments:moderate"
)
const (
// ChannelContentCreate permits creating one's own posts in a channel.
ChannelContentCreate = "channel:content:create"
)
const (
// ChannelContentEditOwn permits editing and publishing one's own channel posts.
ChannelContentEditOwn = "channel:content:edit-own"
)
const (
// ChannelContentWrite permits editing every post and version in the channel.
ChannelContentWrite = "channel:content:write"
)
const (
// ChannelMediaWrite permits uploading and editing the channel's media.
ChannelMediaWrite = "channel:media:write"
)
const (
// ChannelSettingsManage permits changing channel settings and lifecycle.
ChannelSettingsManage = "channel:settings:manage"
)
const HeldLimit = 1000
HeldLimit is the keys one billing read returns per keyspace; a viewer holding more gets an incomplete Filter.
const ( // MaxKeyBytes bounds a key: <tenant>:content:<id>/<version>. MaxKeyBytes = maxTenant + len(":content:") + 36 + 1 + 36 )
Variables ¶
var ErrNotContentKey = errors.New("access: not a content key")
ErrNotContentKey is a string outside the key grammar.
var ErrRule = errors.New("access: invalid rule")
ErrRule is a rule outside the grammar or naming an undeclared tier.
Functions ¶
func ChannelPermissions ¶ added in v0.131.0
func ChannelPermissions() []string
ChannelPermissions lists the capabilities hosts may bundle into channel roles.
func ChannelPrefix ¶ added in v0.131.0
ChannelPrefix is the keyspace of a tenant's channel keys.
func ContentPrefix ¶ added in v0.81.0
ContentPrefix is the keyspace of a tenant's content and version keys.
func Names ¶ added in v0.71.0
func Names(ps ...Permission) []string
Names is ps as strings, as an auth's role catalog declares them.
func ValidTenant ¶ added in v0.81.0
ValidTenant reports a tenant id usable in keys: [a-z0-9_-]{1,64}.
Types ¶
type AccountMembership ¶ added in v0.92.0
type AccountMembership struct{ ID string }
AccountMembership identifies an existing account in the target tenant. ID is empty for an actor who can administer the tenant but is not a member.
type Actor ¶
type Actor struct {
ID string // the subject (auth.Identity.Subject); empty when Anonymous
// Account records membership in the engine's tenant independently of the
// source actor. A nonnil empty membership is a verified actor from another
// tenant; it grants no audience identity or ownership shortcut here.
// Nil retains the legacy host contract that a person's ID is its account ID.
Account *AccountMembership
// Kind is the subject's kind: a person (auth.SubjectUser) or an
// application (auth.SubjectApplication).
Kind auth.SubjectKind
// Invoker is who acts on the subject's behalf; zero when the subject acts
// for itself.
Invoker auth.Invoker
// IP is the client's address (the request's RemoteAddr): the key of an
// anonymous actor's reactions, votes and limits.
IP string
Anonymous bool
// Verified is the request's verified credential, kept for that request
// alone: Can asks it. Nil for an anonymous actor.
Verified auth.Verified
}
Actor is the caller. ContentKit's routes build it from the host's auth.Authenticator: the Verified's Identity, or anonymous when the request carries no credential.
func (Actor) AccountID ¶ added in v0.92.0
AccountID is the actor's audience account in the current tenant, if any. A global operator keeps its source ID for audit but has no implicit account in a different tenant.
func (Actor) Can ¶ added in v0.71.0
Can reports whether the actor holds exactly permission in scope, asking its Verified (auth.PermissionChecker). Anonymous, without a Verified or without the capability it holds nothing. An error never grants.
type Answer ¶ added in v0.66.0
type Answer struct {
Keys map[string]bool // every requested key; absent means not held
Held map[string]HeldKeys // one entry per requested prefix
}
Answer answers a Query.
type Billing ¶ added in v0.81.0
type Billing interface {
// Held answers q for subject in one read. A subject that cannot hold
// keys (no customer id) answers an empty Answer, not an error.
Held(ctx context.Context, subject string, q Query) (Answer, error)
}
Billing reads authoritative entitlement grants from the billing service. Products, prices, checkout, subscriptions and grants are managed directly through that service's API; ContentKit does not copy its catalog or queue billing mutations. adapters/openrails supports embedded and HTTP clients.
type Entitled ¶ added in v0.81.0
type Entitled interface {
Entitlements() []string
}
Entitled is an optional capability of an actor's auth.Verified: the entitlement claims its verified token carries. The Gate answers a tier in kinds.Config.TokenClaims from them without a billing read, so a refund keeps such a tier until the token expires.
type Facet ¶ added in v0.81.0
Facet is a rule as the content_facets listing projection stores it: access_level, access_tiers, access_group_id and access_releases.
type HeldKeys ¶ added in v0.66.0
HeldKeys is the keys a subject holds under one prefix, in byte order.
type Item ¶ added in v0.66.0
type Item struct {
Content string
Version string
// Rule is the version's effective rule (Effective).
Rule Rule
}
Item is one independently accessible version. Content identifies its catalog grouping; Version is required and is the entitlement boundary.
type Key ¶ added in v0.66.0
type Key struct {
// contains filtered or unexported fields
}
Key is an entitlement key ContentKit gives meaning to. OpenRails stores keys opaquely; construct them here, never by hand. The zero Key is invalid.
func ChannelKey ¶ added in v0.131.0
ChannelKey is the key of channel id.
func ContentKey
deprecated
added in
v0.81.0
ContentKey identifies a legacy parent grant for audit and explicit migration. It never opens a version. New products must use VersionKey for each item.
Deprecated: Use VersionKey for audience access. ContentKey remains for explicitly auditing and migrating old billing records.
func ParseKey ¶ added in v0.66.0
ParseKey parses a key string. Anything outside the grammar is ErrNotContentKey, a bare string that is not a valid tier name included.
func VersionKey ¶ added in v0.81.0
VersionKey is the key of one version of content.
func (Key) MarshalText ¶ added in v0.66.0
MarshalText refuses the zero Key.
func (*Key) UnmarshalText ¶ added in v0.66.0
UnmarshalText parses with ParseKey.
type KeyKind ¶ added in v0.66.0
type KeyKind uint8
KeyKind says what an entitlement key grants.
const ( KeyContent KeyKind = iota + 1 // <tenant>:content:<id>: legacy parent grant; audit/migration only KeyVersion // <tenant>:content:<id>/<version>: one version KeyChannel // <tenant>:group:<id>: a channel membership named by an explicit rule KeyTier // <tier>: a tier from config, such as premium )
type Level ¶ added in v0.66.0
type Level string
Level is a rule's access level. The stored group/group_ppv spellings remain stable encodings for channel access, including already recorded releases.
const (
ChannelLevel Level = "group" // holders of Rule.ChannelID's key: members-only content
)
const (
ChannelPPV Level = "group_ppv" // buyers; buying needs Rule.ChannelID's key first
)
const (
PPV Level = "ppv" // buyers of this version
)
const (
Public Level = "public" // anyone
)
const (
TierLevel Level = "tier" // holders of any of Rule.Tiers
)
type Mode ¶ added in v0.81.0
type Mode string
Mode is a listing's access mode.
const ( // Hide lists only what the viewer opens (a purchased library). Hide Mode = "hide" )
const ( // Lock lists everything; Decide marks what stays locked. Lock Mode = "lock" )
type Permission ¶ added in v0.71.0
type Permission string
Permission is a ContentKit application permission: a full root:<resource>:<action> name, held in the root scope of the host's auth (auth.Root) and checked there by the Verified's Can. ContentKit names them; a host declares them in its auth's roles from these constants (AuthKit: rbac.Root.Declare) and never spells one out.
const ( // AccountsLifecycle: deliver AuthKit's account lifecycle (deleted, // restored, purged) to ContentKit over HTTP (a host service). AccountsLifecycle Permission = "root:accounts:lifecycle" )
const ( // AvatarsWrite: upload, edit and remove anyone's avatar on the avatar // primary, exempt from limits: staff, and another site forwarding its // people's (AvatarsConfig.Key). AvatarsWrite Permission = "root:avatars:write" )
const ( // ChannelsWrite: manage channel identity, lifecycle and configuration. ChannelsWrite Permission = "root:channels:write" )
const ( // CommentsBan: ban users from commenting anywhere in the tenant. CommentsBan Permission = "root:comments:ban" )
const ( // CommentsModerate: edit, delete and restore anyone's comments, and list // every comment. CommentsModerate Permission = "root:comments:moderate" )
const ( // ContentCreate: a signed-in person may create their own content outside // a channel. Channel posts require that channel's create or write grant. ContentCreate Permission = "root:content:create" )
const ( // ContentEditOwn: edit and publish content created by this account outside // a channel. Channel posts need the channel edit-own or broad write grant. ContentEditOwn Permission = "root:content:edit-own" )
const ( // ContentViewRestricted: see every content item, whatever its state, // listing, site scope or access, and the site's content statistics. ContentViewRestricted Permission = "root:content:view-restricted" )
const ( // ContentWrite: create, edit, publish, delete and restore any content // item, and see everything. ContentWrite Permission = "root:content:write" )
const ( // EntitiesWrite: create, edit, merge and delete entities, and set content's // memberships. EntitiesWrite Permission = "root:entities:write" )
const ( // ImportWrite: bulk-import content, entities, interactions and signals (a // legacy importer). ImportWrite Permission = "root:import:write" )
const ( // ModerationReview: list and resolve held comments and content. ModerationReview Permission = "root:moderation:review" )
const ( // NotificationsPublish: publish notices to users' inboxes (a host service). NotificationsPublish Permission = "root:notifications:publish" )
const ( // PollsWrite: create, edit and delete polls, their options and images, // and see scheduled and inactive ones. PollsWrite Permission = "root:polls:write" )
func Permissions ¶ added in v0.71.0
func Permissions() []Permission
Permissions is every application permission; hosts choose which roles hold them.
func (Permission) String ¶ added in v0.71.0
func (p Permission) String() string
type Query ¶ added in v0.66.0
type Query struct {
Keys []string // exact keys
Prefixes []string // each ending in ':'
Limit int // keys per prefix; 0 is HeldLimit
}
Query is one entitlement read: exact keys and keyspace prefixes.
type Release ¶ added in v0.117.0
type Release struct {
At time.Time `json:"at"`
Level Level `json:"level"`
Tiers []string `json:"tiers,omitempty"`
ChannelID string `json:"group_id,omitempty"`
}
Release grants an additional audience access at At. It never removes rights granted by the base rule or an earlier release. At is bounded by the content and version publication dates. Tier names have no implicit rank.
type Rule ¶ added in v0.66.0
type Rule struct {
Level Level `json:"level"`
Tiers []string `json:"tiers,omitempty"` // TierLevel: any of these configured tiers
ChannelID string `json:"group_id,omitempty"` // Stable stored/wire encoding for ChannelLevel and ChannelPPV.
// Preview is the part a viewer who does not open it may still read.
Preview *Preview `json:"preview,omitempty"`
// Releases add audiences at their release time; earlier rights remain.
Releases []Release `json:"releases,omitempty"`
}
Rule is stored as JSON on content and its versions. Channel-owned content keeps its editable rule on the overall item; publication snapshots each version's effective rule. A version also opens to holders of its exact version key. Metadata associations never grant access.
func (Rule) AudienceTiers ¶ added in v0.117.0
AudienceTiers is the union of tier audiences released at now. Public access is reported separately by Free; entity/PPV rights require entitlement checks.
func (Rule) Previewed ¶ added in v0.86.0
Previewed is r with its content kind's locked preview when r locks and names none of its own.
func (*Rule) UnmarshalJSON ¶ added in v0.81.0
UnmarshalJSON refuses unknown fields; Validate checks the rest.
type TenureReader ¶ added in v0.89.0
type TenureReader interface {
Tenure(ctx context.Context, subject string, keys []string, at time.Time) (map[string]int64, error)
}
TenureReader optionally extends Billing with elapsed access to its entitlement keys. Tenure answers seconds per requested key as of at, merging overlapping product-access windows and excluding future time. An unavailable history returns an error, not an invented zero. Adapters may implement it to populate the reader's account statistics without a host-specific endpoint.