organization

package
v0.27.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 31, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package organization defines event names and typed event payloads published by the Organization plugin on the global EventBus.

Package organization provides multi-tenancy, role-based access control (RBAC), team structures, and invitation management capabilities for the go-modular-auth ecosystem.

Index

Constants

View Source
const (
	// Organization Events
	EventOrgCreateBefore    = "org:create:before"
	EventOrgCreateAfter     = "org:create:after"
	EventOrgUpdateBefore    = "org:update:before"
	EventOrgUpdateAfter     = "org:update:after"
	EventOrgDeleteBefore    = "org:delete:before"
	EventOrgDeleteAfter     = "org:delete:after"
	EventOrgSetActiveBefore = "org:set_active:before"
	EventOrgSetActiveAfter  = "org:set_active:after"

	// Member Events
	EventMemberAddBefore        = "org:member:add:before"
	EventMemberAddAfter         = "org:member:add:after"
	EventMemberRemoveBefore     = "org:member:remove:before"
	EventMemberRemoveAfter      = "org:member:remove:after"
	EventMemberRoleUpdateBefore = "org:member:role_update:before"
	EventMemberRoleUpdateAfter  = "org:member:role_update:after"
	EventMemberLeaveBefore      = "org:member:leave:before"
	EventMemberLeaveAfter       = "org:member:leave:after"

	// Invitation Events
	EventInvitationCreateBefore = "org:invitation:create:before"
	EventInvitationCreateAfter  = "org:invitation:create:after"
	EventInvitationAcceptBefore = "org:invitation:accept:before"
	EventInvitationAcceptAfter  = "org:invitation:accept:after"
	EventInvitationRejectBefore = "org:invitation:reject:before"
	EventInvitationRejectAfter  = "org:invitation:reject:after"
	EventInvitationCancelBefore = "org:invitation:cancel:before"
	EventInvitationCancelAfter  = "org:invitation:cancel:after"

	// Team Events
	EventTeamCreateBefore       = "org:team:create:before"
	EventTeamCreateAfter        = "org:team:create:after"
	EventTeamUpdateBefore       = "org:team:update:before"
	EventTeamUpdateAfter        = "org:team:update:after"
	EventTeamDeleteBefore       = "org:team:delete:before"
	EventTeamDeleteAfter        = "org:team:delete:after"
	EventTeamMemberAddBefore    = "org:team_member:add:before"
	EventTeamMemberAddAfter     = "org:team_member:add:after"
	EventTeamMemberRemoveBefore = "org:team_member:remove:before"
	EventTeamMemberRemoveAfter  = "org:team_member:remove:after"
	EventTeamSetActiveBefore    = "org:team:set_active:before"
	EventTeamSetActiveAfter     = "org:team:set_active:after"

	// Dynamic Role Events
	EventRoleCreateBefore = "org:role:create:before"
	EventRoleCreateAfter  = "org:role:create:after"
	EventRoleUpdateBefore = "org:role:update:before"
	EventRoleUpdateAfter  = "org:role:update:after"
	EventRoleDeleteBefore = "org:role:delete:before"
	EventRoleDeleteAfter  = "org:role:delete:after"
)

Event Name Constants

View Source
const (
	// RoleOwner represents the highest administrative role in an organization with full control.
	RoleOwner = "owner"

	// RoleAdmin represents an administrative role with elevated management privileges.
	RoleAdmin = "admin"

	// RoleMember represents a standard member role with default read permissions.
	RoleMember = "member"
)

Standard predefined role names within an organization.

View Source
const (
	// ResourceOrganization targets organization-level entities and properties.
	ResourceOrganization = "organization"

	// ResourceMember targets organization membership entities.
	ResourceMember = "member"

	// ResourceInvitation targets member invitations.
	ResourceInvitation = "invitation"

	// ResourceTeam targets organizational team entities.
	ResourceTeam = "team"

	// ResourceAccessControl targets dynamic role and permission configurations.
	ResourceAccessControl = "ac"
)

Standard RBAC resource identifiers for access control statements.

View Source
const (
	// ActionCreate represents permission to create new resources.
	ActionCreate = "create"

	// ActionRead represents permission to view or inspect resources.
	ActionRead = "read"

	// ActionUpdate represents permission to modify existing resources.
	ActionUpdate = "update"

	// ActionDelete represents permission to remove resources.
	ActionDelete = "delete"

	// ActionCancel represents permission to cancel invitations or operations.
	ActionCancel = "cancel"
)

Standard RBAC action identifiers for access control statements.

View Source
const (
	// ExtraKeyOrgID stores the organization identifier in dynamic Extra metadata.
	// Expected type: string.
	ExtraKeyOrgID = "org_id"

	// ExtraKeyOrgSlug stores the organization URL-friendly slug in dynamic Extra metadata.
	// Expected type: string.
	ExtraKeyOrgSlug = "org_slug"

	// ExtraKeyOrgName stores the organization display name in dynamic Extra metadata.
	// Expected type: string.
	ExtraKeyOrgName = "org_name"

	// ExtraKeyMemberRole stores the role assigned to a member in dynamic Extra metadata.
	// Expected type: string.
	ExtraKeyMemberRole = "member_role"

	// ExtraKeyTeamID stores the team identifier in dynamic Extra metadata.
	// Expected type: string.
	ExtraKeyTeamID = "team_id"

	// ExtraKeyInviterID stores the user ID of the inviter in dynamic Extra metadata.
	// Expected type: string.
	ExtraKeyInviterID = "inviter_id"

	// ExtraKeyInvitationID stores the invitation identifier in dynamic Extra metadata.
	// Expected type: string.
	ExtraKeyInvitationID = "invitation_id"

	// ExtraKeyUserID stores the associated user identifier in dynamic Extra metadata.
	// Expected type: string.
	ExtraKeyUserID = "user_id"

	// ExtraKeyEmail stores the targeted email address in dynamic Extra metadata.
	// Expected type: string.
	ExtraKeyEmail = "email"
)

Standard Extra metadata keys that can be set or consumed in organization operations and events.

View Source
const (
	// ContextKeyActiveOrgPrefix is the key prefix used when tracking a user's active organization in plugin.Context.
	ContextKeyActiveOrgPrefix = "org:active:"

	// ContextKeyActiveTeamPrefix is the key prefix used when tracking a user's active team in plugin.Context.
	ContextKeyActiveTeamPrefix = "org:team:active:"
)

Shared plugin context key prefixes used for active tenant context in plugin.Context.

View Source
const (
	MemberContextKey       contextKey = "org_member"
	OrganizationContextKey contextKey = "org_entity"
)
View Source
const PluginID = "organization"

PluginID is the unique string identifier for the Organization plugin ("organization").

Variables

View Source
var (
	// ErrOrganizationNotFound is returned when an organization matching the specified criteria does not exist.
	ErrOrganizationNotFound = errors.New("organization not found")

	// ErrOrganizationAlreadyExists is returned when attempting to create an organization that already exists.
	ErrOrganizationAlreadyExists = errors.New("organization already exists")

	// ErrSlugAlreadyExists is returned when the requested slug is already taken by another organization.
	ErrSlugAlreadyExists = errors.New("organization slug already exists")

	// ErrMemberNotFound is returned when a user is not a member of the specified organization.
	ErrMemberNotFound = errors.New("member not found in organization")

	// ErrMemberAlreadyExists is returned when attempting to add a user who is already a member of the organization.
	ErrMemberAlreadyExists = errors.New("member already exists in organization")

	// ErrCannotRemoveLastOwner is returned when attempting to remove or demote the last remaining owner in an organization.
	ErrCannotRemoveLastOwner = errors.New("cannot remove or demote the last owner of the organization")

	// ErrCannotLeaveAsLastOwner is returned when the last owner attempts to leave the organization without transferring ownership.
	ErrCannotLeaveAsLastOwner = errors.New("cannot leave organization as the last owner without transferring ownership")

	// ErrInvitationNotFound is returned when an invitation cannot be found by ID or email.
	ErrInvitationNotFound = errors.New("invitation not found")

	// ErrInvitationExpired is returned when attempting to accept or process an expired invitation.
	ErrInvitationExpired = errors.New("invitation has expired")

	// ErrInvitationAlreadyExists is returned when a pending invitation already exists for the email in the organization.
	ErrInvitationAlreadyExists = errors.New("a pending invitation already exists for this email in the organization")

	// ErrInvalidInvitationStatus is returned when an action requires an invitation in 'pending' status but found otherwise.
	ErrInvalidInvitationStatus = errors.New("invitation status is invalid for this operation")

	// ErrTeamNotFound is returned when a team does not exist in the organization.
	ErrTeamNotFound = errors.New("team not found")

	// ErrTeamAlreadyExists is returned when a team name already exists within the organization.
	ErrTeamAlreadyExists = errors.New("team already exists in organization")

	// ErrTeamMemberNotFound is returned when a user is not a member of the specified team.
	ErrTeamMemberNotFound = errors.New("team member not found")

	// ErrTeamMemberAlreadyExists is returned when a user is already assigned to the specified team.
	ErrTeamMemberAlreadyExists = errors.New("user is already a member of the team")

	// ErrCannotRemoveAllTeams is returned when attempting to delete the last team while AllowRemovingAllTeams is false.
	ErrCannotRemoveAllTeams = errors.New("cannot remove all teams from organization")

	// ErrRoleNotFound is returned when a dynamic role cannot be found in the organization.
	ErrRoleNotFound = errors.New("dynamic role not found")

	// ErrRoleAlreadyExists is returned when a role with the given name already exists in the organization.
	ErrRoleAlreadyExists = errors.New("role name already exists in organization")

	// ErrPermissionDenied is returned when the current user's role lacks sufficient permissions to execute an action.
	ErrPermissionDenied = errors.New("permission denied")

	// ErrOrganizationLimitReached is returned when a user exceeds the allowed limit of created organizations.
	ErrOrganizationLimitReached = errors.New("maximum number of organizations reached")

	// ErrMembershipLimitReached is returned when an organization exceeds its maximum allowed members.
	ErrMembershipLimitReached = errors.New("maximum number of organization members reached")

	// ErrInvitationLimitReached is returned when an organization exceeds its maximum allowed pending invitations.
	ErrInvitationLimitReached = errors.New("maximum number of pending invitations reached")

	// ErrTeamsLimitReached is returned when an organization exceeds its maximum allowed teams.
	ErrTeamsLimitReached = errors.New("maximum number of teams reached")

	// ErrTeamMembersLimitReached is returned when a team exceeds its maximum allowed members.
	ErrTeamMembersLimitReached = errors.New("maximum number of team members reached")

	// ErrRolesLimitReached is returned when an organization exceeds its maximum allowed dynamic roles.
	ErrRolesLimitReached = errors.New("maximum number of dynamic roles reached")

	// ErrTeamsNotEnabled is returned when attempting team operations while the teams sub-module is disabled.
	ErrTeamsNotEnabled = errors.New("teams module is not enabled")

	// ErrDynamicACNotEnabled is returned when attempting dynamic role operations while dynamic AC is disabled.
	ErrDynamicACNotEnabled = errors.New("dynamic access control is not enabled")

	// ErrEmailNotVerified is returned when email verification is required before sending or accepting invitations.
	ErrEmailNotVerified = errors.New("email verification is required for invitations")

	// ErrInvalidParameter is returned when an invalid argument or parameter is supplied to an operation.
	ErrInvalidParameter = errors.New("invalid parameter provided")
)
View Source
var DefaultRoles = map[string]Permissions{
	RoleOwner: {
		ResourceOrganization:  {ActionUpdate, ActionDelete},
		ResourceMember:        {ActionCreate, ActionUpdate, ActionDelete},
		ResourceInvitation:    {ActionCreate, ActionCancel},
		ResourceTeam:          {ActionCreate, ActionUpdate, ActionDelete},
		ResourceAccessControl: {ActionCreate, ActionRead, ActionUpdate, ActionDelete},
	},
	RoleAdmin: {
		ResourceOrganization:  {ActionUpdate},
		ResourceMember:        {ActionCreate, ActionUpdate, ActionDelete},
		ResourceInvitation:    {ActionCreate, ActionCancel},
		ResourceTeam:          {ActionCreate, ActionUpdate, ActionDelete},
		ResourceAccessControl: {ActionCreate, ActionRead, ActionUpdate, ActionDelete},
	},
	RoleMember: {
		ResourceAccessControl: {ActionRead},
	},
}

DefaultRoles defines the baseline permission matrix for built-in roles (owner, admin, member).

Functions

func ActiveOrgContextKey

func ActiveOrgContextKey(userID string) string

ActiveOrgContextKey formats the context store key used to track a user's active organization.

func ActiveTeamContextKey

func ActiveTeamContextKey(userID string) string

ActiveTeamContextKey formats the context store key used to track a user's active team.

func EvaluatePermissions

func EvaluatePermissions(granted, required Permissions) bool

EvaluatePermissions checks if a granted permissions matrix satisfies all required permissions.

func HasAction

func HasAction(actions []string, targetAction string) bool

HasAction checks if a target action is present in an action list (or matches wildcard "*").

Types

type AcceptInvitationParams

type AcceptInvitationParams struct {
	InvitationID string `json:"invitation_id"`
	UserID       string `json:"user_id"`
	plugin.ExtraContainer
}

type AcceptInvitationResult

type AcceptInvitationResult struct {
	Invitation   *Invitation   `json:"invitation"`
	Member       *Member       `json:"member"`
	Organization *Organization `json:"organization"`
}

type AddMemberParams

type AddMemberParams struct {
	OrganizationID string `json:"organization_id"`
	UserID         string `json:"user_id"`
	Role           string `json:"role"`
	InvokingUserID string `json:"invoking_user_id,omitempty"`
	plugin.ExtraContainer
}

type AddMemberResult

type AddMemberResult struct {
	Member *Member `json:"member"`
}

type AddTeamMemberParams

type AddTeamMemberParams struct {
	TeamID         string `json:"team_id"`
	UserID         string `json:"user_id"`
	InvokingUserID string `json:"invoking_user_id,omitempty"`
	plugin.ExtraContainer
}

type AddTeamMemberResult

type AddTeamMemberResult struct {
	TeamMember *TeamMember `json:"team_member"`
}

type AllowOrgCreationFunc

type AllowOrgCreationFunc func(ctx context.Context, userID string) (bool, error)

AllowOrgCreationFunc defines a callback to authorize whether a specific user is permitted to create new organizations.

type CancelInvitationParams

type CancelInvitationParams struct {
	InvitationID string `json:"invitation_id"`
	UserID       string `json:"user_id,omitempty"`
	plugin.ExtraContainer
}

type CancelInvitationResult

type CancelInvitationResult struct {
	Invitation *Invitation `json:"invitation"`
}

type CheckSlugParams

type CheckSlugParams struct {
	Slug string `json:"slug"`
	plugin.ExtraContainer
}

type CheckSlugResult

type CheckSlugResult struct {
	Available bool `json:"available"`
}

type Config

type Config struct {
	// AllowUserToCreateOrganization determines whether a user is authorized to create a new organization.
	AllowUserToCreateOrganization AllowOrgCreationFunc

	// OrganizationLimit restricts the maximum number of organizations a user can create.
	OrganizationLimit OrgLimitFunc

	// CreatorRole specifies the initial role assigned to the user creating an organization (default: "owner").
	CreatorRole string

	// MembershipLimit restricts the maximum number of members per organization.
	MembershipLimit MembershipLimitFunc

	// InvitationExpiresIn defines the validity duration for issued member invitations (default: 48 hours).
	InvitationExpiresIn time.Duration

	// InvitationLimit restricts the maximum number of pending invitations per organization.
	InvitationLimit InvitationLimitFunc

	// CancelPendingInvitationsOnReInvite automatically cancels previous pending invitations when re-inviting the same email.
	CancelPendingInvitationsOnReInvite bool

	// RequireEmailVerificationOnInvitation enforces that the invited recipient email must be verified.
	RequireEmailVerificationOnInvitation bool

	// SendInvitationEmail is an optional delivery callback invoked whenever an invitation is created.
	SendInvitationEmail SendInvitationEmailFunc

	// TeamsEnabled enables the sub-module for organizational teams and team memberships.
	TeamsEnabled bool

	// DefaultTeamEnabled automatically creates an initial default team upon organization creation.
	DefaultTeamEnabled bool

	// AllowRemovingAllTeams permits deleting all teams in an organization (default: true).
	AllowRemovingAllTeams bool

	// MaximumTeams restricts the maximum number of teams per organization.
	MaximumTeams MaxTeamsFunc

	// MaximumMembersPerTeam restricts the maximum number of members per team.
	MaximumMembersPerTeam MaxMembersPerTeamFunc

	// DynamicAccessControlEnabled enables database-persisted dynamic roles and custom permission matrices.
	DynamicAccessControlEnabled bool

	// MaximumRolesPerOrganization restricts the maximum number of dynamic roles per organization.
	MaximumRolesPerOrganization MaxRolesFunc

	// CustomRoles defines static custom roles and their granted permission matrices.
	CustomRoles map[string]Permissions
}

Config holds all configuration settings and callbacks for the Organization plugin.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns baseline production-ready defaults for the Organization plugin.

type CreateInvitationParams

type CreateInvitationParams struct {
	OrganizationID string  `json:"organization_id"`
	InviterID      string  `json:"inviter_id"`
	Email          string  `json:"email"`
	Role           string  `json:"role"`
	TeamID         *string `json:"team_id,omitempty"`
	plugin.ExtraContainer
}

type CreateInvitationResult

type CreateInvitationResult struct {
	Invitation *Invitation `json:"invitation"`
}

type CreateOrganizationParams

type CreateOrganizationParams struct {
	UserID   string         `json:"user_id"`
	Name     string         `json:"name"`
	Slug     string         `json:"slug,omitempty"`
	Metadata map[string]any `json:"metadata,omitempty"`
	plugin.ExtraContainer
}

type CreateOrganizationResult

type CreateOrganizationResult struct {
	Organization *Organization `json:"organization"`
	Member       *Member       `json:"member"`
}

type CreateRoleParams

type CreateRoleParams struct {
	OrganizationID string              `json:"organization_id"`
	UserID         string              `json:"user_id,omitempty"`
	Role           string              `json:"role"`
	Permissions    map[string][]string `json:"permissions"`
	plugin.ExtraContainer
}

type CreateRoleResult

type CreateRoleResult struct {
	Role *OrganizationRole `json:"role"`
}

type CreateTeamParams

type CreateTeamParams struct {
	OrganizationID string `json:"organization_id"`
	UserID         string `json:"user_id,omitempty"`
	Name           string `json:"name"`
	plugin.ExtraContainer
}

type CreateTeamResult

type CreateTeamResult struct {
	Team *Team `json:"team"`
}

type DeleteOrganizationParams

type DeleteOrganizationParams struct {
	OrganizationID string `json:"organization_id"`
	UserID         string `json:"user_id,omitempty"`
	plugin.ExtraContainer
}

type DeleteOrganizationResult

type DeleteOrganizationResult struct {
	Success bool `json:"success"`
}

type DeleteRoleParams

type DeleteRoleParams struct {
	RoleID string `json:"role_id"`
	UserID string `json:"user_id,omitempty"`
	plugin.ExtraContainer
}

type DeleteRoleResult

type DeleteRoleResult struct {
	Success bool `json:"success"`
}

type DeleteTeamParams

type DeleteTeamParams struct {
	TeamID string `json:"team_id"`
	UserID string `json:"user_id,omitempty"`
	plugin.ExtraContainer
}

type DeleteTeamResult

type DeleteTeamResult struct {
	Success bool `json:"success"`
}

type GetActiveMemberParams

type GetActiveMemberParams struct {
	UserID         string `json:"user_id"`
	OrganizationID string `json:"organization_id,omitempty"`
	plugin.ExtraContainer
}

type GetActiveMemberResult

type GetActiveMemberResult struct {
	Member *Member `json:"member"`
}

type GetActiveMemberRoleParams

type GetActiveMemberRoleParams struct {
	UserID         string `json:"user_id"`
	OrganizationID string `json:"organization_id,omitempty"`
	plugin.ExtraContainer
}

type GetActiveMemberRoleResult

type GetActiveMemberRoleResult struct {
	Role string `json:"role"`
}

type GetActiveOrganizationParams

type GetActiveOrganizationParams struct {
	UserID string `json:"user_id"`
	plugin.ExtraContainer
}

type GetActiveOrganizationResult

type GetActiveOrganizationResult struct {
	Organization *Organization `json:"organization"`
	Member       *Member       `json:"member"`
}

type GetActiveTeamParams

type GetActiveTeamParams struct {
	UserID string `json:"user_id"`
	plugin.ExtraContainer
}

type GetActiveTeamResult

type GetActiveTeamResult struct {
	Team *Team `json:"team"`
}

type GetFullOrganizationParams

type GetFullOrganizationParams struct {
	OrganizationID string `json:"organization_id"`
	plugin.ExtraContainer
}

type GetFullOrganizationResult

type GetFullOrganizationResult struct {
	Organization *Organization `json:"organization"`
	Members      []*Member     `json:"members"`
	Invitations  []*Invitation `json:"invitations"`
	Teams        []*Team       `json:"teams,omitempty"`
}

type GetInvitationParams

type GetInvitationParams struct {
	InvitationID string `json:"invitation_id"`
	plugin.ExtraContainer
}

type GetInvitationResult

type GetInvitationResult struct {
	Invitation *Invitation `json:"invitation"`
}

type GetMemberParams

type GetMemberParams struct {
	OrganizationID string `json:"organization_id"`
	UserID         string `json:"user_id"`
	plugin.ExtraContainer
}

type GetMemberResult

type GetMemberResult struct {
	Member *Member `json:"member"`
}

type GetOrganizationBySlugParams

type GetOrganizationBySlugParams struct {
	Slug string `json:"slug"`
	plugin.ExtraContainer
}

type GetOrganizationBySlugResult

type GetOrganizationBySlugResult struct {
	Organization *Organization `json:"organization"`
}

type GetOrganizationParams

type GetOrganizationParams struct {
	OrganizationID string `json:"organization_id"`
	plugin.ExtraContainer
}

type GetOrganizationResult

type GetOrganizationResult struct {
	Organization *Organization `json:"organization"`
}

type GetRoleParams

type GetRoleParams struct {
	RoleID string `json:"role_id"`
	plugin.ExtraContainer
}

type GetRoleResult

type GetRoleResult struct {
	Role *OrganizationRole `json:"role"`
}

type GetTeamParams

type GetTeamParams struct {
	TeamID string `json:"team_id"`
	plugin.ExtraContainer
}

type GetTeamResult

type GetTeamResult struct {
	Team *Team `json:"team"`
}

type HasPermissionParams

type HasPermissionParams struct {
	OrganizationID string      `json:"organization_id"`
	UserID         string      `json:"user_id,omitempty"`
	Role           string      `json:"role,omitempty"`
	Permissions    Permissions `json:"permissions"`
	plugin.ExtraContainer
}

type HasPermissionResult

type HasPermissionResult struct {
	HasPermission bool `json:"has_permission"`
}

type Invitation

type Invitation struct {
	// ID is the unique invitation identifier.
	ID string `json:"id"`

	// OrganizationID identifies the organization to which the user is invited.
	OrganizationID string `json:"organizationId"`

	// Email is the recipient email address.
	Email string `json:"email"`

	// Role is the role to be assigned upon accepting the invitation.
	Role string `json:"role"`

	// Status indicates the current lifecycle status of the invitation.
	Status InvitationStatus `json:"status"`

	// TeamID optionally associates an initial team assignment upon accepting.
	TeamID *string `json:"teamId,omitempty"`

	// InviterID identifies the user who dispatched the invitation.
	InviterID string `json:"inviterId"`

	// ExpiresAt specifies the exact timestamp when the invitation expires.
	ExpiresAt time.Time `json:"expiresAt"`

	// CreatedAt marks when the invitation was issued.
	CreatedAt time.Time `json:"createdAt"`
}

Invitation represents an email invitation dispatched to invite a user into an organization.

type InvitationAcceptAfterEventPayload

type InvitationAcceptAfterEventPayload struct {
	Invitation   *Invitation
	Member       *Member
	Organization *Organization
	plugin.ExtraContainer
}

type InvitationAcceptBeforeEventPayload

type InvitationAcceptBeforeEventPayload struct {
	InvitationID string
	UserID       string
	plugin.ExtraContainer
}

type InvitationCancelAfterEventPayload

type InvitationCancelAfterEventPayload struct {
	Invitation *Invitation
	plugin.ExtraContainer
}

type InvitationCancelBeforeEventPayload

type InvitationCancelBeforeEventPayload struct {
	InvitationID string
	UserID       string
	plugin.ExtraContainer
}

type InvitationCreateAfterEventPayload

type InvitationCreateAfterEventPayload struct {
	Invitation *Invitation
	plugin.ExtraContainer
}

type InvitationCreateBeforeEventPayload

type InvitationCreateBeforeEventPayload struct {
	OrganizationID string
	InviterID      string
	Email          string
	Role           string
	TeamID         *string
	plugin.ExtraContainer
}

type InvitationEmailData

type InvitationEmailData struct {
	// Invitation is the newly created invitation record.
	Invitation *Invitation

	// Organization is the organization domain record.
	Organization *Organization

	// InviterID is the user ID of the inviter.
	InviterID string

	// InviterEmail is the email of the inviter if resolved.
	InviterEmail string

	// InviterName is the display name of the inviter if resolved.
	InviterName string
}

InvitationEmailData holds payload information passed to SendInvitationEmailFunc when an invitation is dispatched.

type InvitationLimitFunc

type InvitationLimitFunc func(ctx context.Context, orgID string) (int, error)

InvitationLimitFunc defines a callback returning the maximum number of active pending invitations for an organization.

type InvitationRejectAfterEventPayload

type InvitationRejectAfterEventPayload struct {
	Invitation *Invitation
	plugin.ExtraContainer
}

type InvitationRejectBeforeEventPayload

type InvitationRejectBeforeEventPayload struct {
	InvitationID string
	UserID       string
	plugin.ExtraContainer
}

type InvitationRepository added in v0.27.2

type InvitationRepository interface {
	// CreateInvitation persists a new email invitation to join an organization.
	CreateInvitation(ctx context.Context, invitation *Invitation) error

	// GetInvitationByID retrieves an invitation record by ID.
	GetInvitationByID(ctx context.Context, id string) (*Invitation, error)

	// GetPendingInvitation retrieves an active pending invitation by organization ID and email.
	GetPendingInvitation(ctx context.Context, orgID, email string) (*Invitation, error)

	// UpdateInvitation updates the status (e.g. accepted, revoked, expired) of an invitation.
	UpdateInvitation(ctx context.Context, invitation *Invitation) error

	// DeleteInvitation removes an invitation record from storage.
	DeleteInvitation(ctx context.Context, id string) error

	// ListInvitationsByOrgID lists invitations for an organization, optionally filtered by status.
	ListInvitationsByOrgID(ctx context.Context, orgID string, status *InvitationStatus) ([]*Invitation, error)

	// ListInvitationsByEmail lists invitations sent to a user's email across all organizations.
	ListInvitationsByEmail(ctx context.Context, email string, status *InvitationStatus) ([]*Invitation, error)

	// CountPendingInvitations returns the count of active pending invitations for an org.
	CountPendingInvitations(ctx context.Context, orgID string) (int, error)
}

InvitationRepository defines the persistence operations for organization invitations.

type InvitationStatus

type InvitationStatus string

InvitationStatus defines the string enum for invitation lifecycle states.

const (
	// InvitationStatusPending represents an issued invitation awaiting recipient acceptance or rejection.
	InvitationStatusPending InvitationStatus = "pending"

	// InvitationStatusAccepted represents an invitation that was successfully accepted by the invitee.
	InvitationStatusAccepted InvitationStatus = "accepted"

	// InvitationStatusRejected represents an invitation that was explicitly declined by the invitee.
	InvitationStatusRejected InvitationStatus = "rejected"

	// InvitationStatusCanceled represents an invitation revoked by an organization administrator.
	InvitationStatusCanceled InvitationStatus = "canceled"
)

type LeaveOrganizationParams

type LeaveOrganizationParams struct {
	OrganizationID string `json:"organization_id"`
	UserID         string `json:"user_id"`
	plugin.ExtraContainer
}

type LeaveOrganizationResult

type LeaveOrganizationResult struct {
	Success bool `json:"success"`
}

type ListInvitationsParams

type ListInvitationsParams struct {
	OrganizationID string            `json:"organization_id"`
	Status         *InvitationStatus `json:"status,omitempty"`
	plugin.ExtraContainer
}

type ListInvitationsResult

type ListInvitationsResult struct {
	Invitations []*Invitation `json:"invitations"`
}

type ListMembersParams

type ListMembersParams struct {
	OrganizationID string `json:"organization_id"`
	Limit          int    `json:"limit,omitempty"`
	Offset         int    `json:"offset,omitempty"`
	plugin.ExtraContainer
}

type ListMembersResult

type ListMembersResult struct {
	Members []*Member `json:"members"`
	Total   int       `json:"total"`
}

type ListOrganizationsParams

type ListOrganizationsParams struct {
	UserID string `json:"user_id"`
	plugin.ExtraContainer
}

type ListOrganizationsResult

type ListOrganizationsResult struct {
	Organizations []*Organization `json:"organizations"`
}

type ListRolesParams

type ListRolesParams struct {
	OrganizationID string `json:"organization_id"`
	plugin.ExtraContainer
}

type ListRolesResult

type ListRolesResult struct {
	Roles []*OrganizationRole `json:"roles"`
}

type ListTeamMembersParams

type ListTeamMembersParams struct {
	TeamID string `json:"team_id"`
	plugin.ExtraContainer
}

type ListTeamMembersResult

type ListTeamMembersResult struct {
	Members []*TeamMember `json:"members"`
}

type ListTeamsParams

type ListTeamsParams struct {
	OrganizationID string `json:"organization_id"`
	UserID         string `json:"user_id,omitempty"`
	plugin.ExtraContainer
}

type ListTeamsResult

type ListTeamsResult struct {
	Teams []*Team `json:"teams"`
}

type ListUserInvitationsParams

type ListUserInvitationsParams struct {
	Email  string            `json:"email"`
	Status *InvitationStatus `json:"status,omitempty"`
	plugin.ExtraContainer
}

type ListUserInvitationsResult

type ListUserInvitationsResult struct {
	Invitations []*Invitation `json:"invitations"`
}

type MaxMembersPerTeamFunc

type MaxMembersPerTeamFunc func(ctx context.Context, teamID string) (int, error)

MaxMembersPerTeamFunc defines a callback returning the maximum number of members a team can hold.

type MaxRolesFunc

type MaxRolesFunc func(ctx context.Context, orgID string) (int, error)

MaxRolesFunc defines a callback returning the maximum number of dynamic roles an organization can configure.

type MaxTeamsFunc

type MaxTeamsFunc func(ctx context.Context, orgID string) (int, error)

MaxTeamsFunc defines a callback returning the maximum number of teams an organization can create.

type Member

type Member struct {
	// ID is the unique identifier for the membership record.
	ID string `json:"id"`

	// OrganizationID identifies the parent organization.
	OrganizationID string `json:"organizationId"`

	// UserID identifies the associated user.
	UserID string `json:"userId"`

	// Role is the assigned role name (e.g. "owner", "admin", "member", or comma-separated compound roles).
	Role string `json:"role"`

	// CreatedAt marks when the user joined the organization.
	CreatedAt time.Time `json:"createdAt"`

	// UpdatedAt marks when the membership record was last updated.
	UpdatedAt *time.Time `json:"updatedAt,omitempty"`

	// User contains enriched user profile information when populated.
	User *UserInfo `json:"user,omitempty"`
}

Member represents the membership relation connecting a user to an organization with an assigned role.

type MemberAddAfterEventPayload

type MemberAddAfterEventPayload struct {
	Member *Member
	plugin.ExtraContainer
}

type MemberAddBeforeEventPayload

type MemberAddBeforeEventPayload struct {
	OrganizationID string
	UserID         string
	Role           string
	plugin.ExtraContainer
}

type MemberLeaveAfterEventPayload

type MemberLeaveAfterEventPayload struct {
	OrganizationID string
	UserID         string
	plugin.ExtraContainer
}

type MemberLeaveBeforeEventPayload

type MemberLeaveBeforeEventPayload struct {
	OrganizationID string
	UserID         string
	plugin.ExtraContainer
}

type MemberRemoveAfterEventPayload

type MemberRemoveAfterEventPayload struct {
	OrganizationID string
	UserID         string
	plugin.ExtraContainer
}

type MemberRemoveBeforeEventPayload

type MemberRemoveBeforeEventPayload struct {
	OrganizationID string
	UserID         string
	plugin.ExtraContainer
}

type MemberRepository added in v0.27.2

type MemberRepository interface {
	// CreateMember adds a user to an organization with an assigned role.
	CreateMember(ctx context.Context, member *Member) error

	// GetMember retrieves a membership record linking a user to an organization.
	GetMember(ctx context.Context, orgID, userID string) (*Member, error)

	// GetMemberByID retrieves a membership record by its primary key ID.
	GetMemberByID(ctx context.Context, memberID string) (*Member, error)

	// UpdateMember updates the assigned role of an organization member.
	UpdateMember(ctx context.Context, member *Member) error

	// DeleteMember removes a member from an organization.
	DeleteMember(ctx context.Context, orgID, userID string) error

	// ListMembers retrieves a paginated list of organization members with enriched user profiles.
	ListMembers(ctx context.Context, orgID string, limit, offset int) ([]*Member, int, error)

	// CountMembersByRole returns the number of members holding a specific role in an organization.
	CountMembersByRole(ctx context.Context, orgID, role string) (int, error)

	// CountMembers returns the total member count in an organization.
	CountMembers(ctx context.Context, orgID string) (int, error)
}

MemberRepository defines the persistence operations for organization membership relations.

type MemberRoleUpdateAfterEventPayload

type MemberRoleUpdateAfterEventPayload struct {
	Member *Member
	plugin.ExtraContainer
}

type MemberRoleUpdateBeforeEventPayload

type MemberRoleUpdateBeforeEventPayload struct {
	OrganizationID string
	UserID         string
	NewRole        string
	plugin.ExtraContainer
}

type MembershipLimitFunc

type MembershipLimitFunc func(ctx context.Context, orgID string) (int, error)

MembershipLimitFunc defines a callback returning the maximum number of members an organization can have.

type Option

type Option func(*Config)

Option configures the Organization plugin.

func WithAllowUserToCreateOrganization

func WithAllowUserToCreateOrganization(fn AllowOrgCreationFunc) Option

WithAllowUserToCreateOrganization sets a functional callback to validate organization creation permission.

func WithCancelPendingInvitationsOnReInvite

func WithCancelPendingInvitationsOnReInvite(cancel bool) Option

WithCancelPendingInvitationsOnReInvite controls whether existing pending invitations are auto-canceled on re-invitations.

func WithCreatorRole

func WithCreatorRole(role string) Option

WithCreatorRole sets the default role assigned to the user creating an organization.

func WithCustomRoles

func WithCustomRoles(roles map[string]Permissions) Option

WithCustomRoles registers custom static roles and their permission matrices.

func WithDynamicAccessControl

func WithDynamicAccessControl(enabled bool) Option

WithDynamicAccessControl enables or disables dynamic organization-scoped roles.

func WithDynamicAccessControlLimits

func WithDynamicAccessControlLimits(maxRoles MaxRolesFunc) Option

WithDynamicAccessControlLimits sets dynamic callbacks for role limits per organization.

func WithInvitationExpiresIn

func WithInvitationExpiresIn(duration time.Duration) Option

WithInvitationExpiresIn sets the expiration duration for issued member invitations.

func WithInvitationLimit

func WithInvitationLimit(limit int) Option

WithInvitationLimit sets a static maximum number of pending invitations per organization.

func WithInvitationLimitFunc

func WithInvitationLimitFunc(fn InvitationLimitFunc) Option

WithInvitationLimitFunc sets a dynamic callback to calculate pending invitation limits.

func WithMembershipLimit

func WithMembershipLimit(limit int) Option

WithMembershipLimit sets a static maximum limit of members per organization.

func WithMembershipLimitFunc

func WithMembershipLimitFunc(fn MembershipLimitFunc) Option

WithMembershipLimitFunc sets a dynamic callback to calculate membership limits.

func WithOrganizationLimit

func WithOrganizationLimit(limit int) Option

WithOrganizationLimit sets a static maximum number of organizations a user can create.

func WithOrganizationLimitFunc

func WithOrganizationLimitFunc(fn OrgLimitFunc) Option

WithOrganizationLimitFunc sets a dynamic callback to calculate organization creation limits per user.

func WithRequireEmailVerificationOnInvitation

func WithRequireEmailVerificationOnInvitation(require bool) Option

WithRequireEmailVerificationOnInvitation controls whether email verification is required for invitations.

func WithSendInvitationEmail

func WithSendInvitationEmail(fn SendInvitationEmailFunc) Option

WithSendInvitationEmail configures an external delivery callback for dispatching invitation emails.

func WithTeams

func WithTeams(enabled, defaultTeam, allowRemovingAll bool) Option

WithTeams configures the teams sub-module, default team creation, and deletion rules.

func WithTeamsLimits

func WithTeamsLimits(maxTeams MaxTeamsFunc, maxMembers MaxMembersPerTeamFunc) Option

WithTeamsLimits sets dynamic callbacks for team and team-membership limits.

type OrgCreateAfterEventPayload

type OrgCreateAfterEventPayload struct {
	Organization *Organization
	Member       *Member
	plugin.ExtraContainer
}

type OrgCreateBeforeEventPayload

type OrgCreateBeforeEventPayload struct {
	UserID   string
	Name     string
	Slug     string
	Metadata map[string]any
	plugin.ExtraContainer
}

type OrgDeleteAfterEventPayload

type OrgDeleteAfterEventPayload struct {
	OrganizationID string
	plugin.ExtraContainer
}

type OrgDeleteBeforeEventPayload

type OrgDeleteBeforeEventPayload struct {
	OrganizationID string
	plugin.ExtraContainer
}

type OrgLimitFunc

type OrgLimitFunc func(ctx context.Context, userID string) (int, error)

OrgLimitFunc defines a callback returning the maximum number of organizations a user can create.

type OrgRepository added in v0.27.2

type OrgRepository interface {
	// CreateOrganization persists a new organization tenant boundary in storage.
	CreateOrganization(ctx context.Context, org *Organization) error

	// GetOrganizationByID retrieves an organization record by its unique ID.
	GetOrganizationByID(ctx context.Context, id string) (*Organization, error)

	// GetOrganizationBySlug retrieves an organization record by its unique URL slug.
	GetOrganizationBySlug(ctx context.Context, slug string) (*Organization, error)

	// UpdateOrganization updates mutable fields of an organization.
	UpdateOrganization(ctx context.Context, org *Organization) error

	// DeleteOrganization permanently removes an organization record and cascades related data.
	DeleteOrganization(ctx context.Context, id string) error

	// ListOrganizationsByUserID retrieves all organizations in which a user holds active membership.
	ListOrganizationsByUserID(ctx context.Context, userID string) ([]*Organization, error)
}

OrgRepository defines the persistence operations for organization tenant boundaries.

type OrgSetActiveAfterEventPayload

type OrgSetActiveAfterEventPayload struct {
	UserID         string
	OrganizationID string
	Organization   *Organization
	Member         *Member
	plugin.ExtraContainer
}

type OrgSetActiveBeforeEventPayload

type OrgSetActiveBeforeEventPayload struct {
	UserID         string
	OrganizationID string
	plugin.ExtraContainer
}

type OrgUpdateAfterEventPayload

type OrgUpdateAfterEventPayload struct {
	Organization *Organization
	plugin.ExtraContainer
}

type OrgUpdateBeforeEventPayload

type OrgUpdateBeforeEventPayload struct {
	OrganizationID string
	Name           *string
	Slug           *string
	Metadata       map[string]any
	plugin.ExtraContainer
}

type Organization

type Organization struct {
	// ID is the unique string identifier for the organization.
	ID string `json:"id"`

	// Name is the display name of the organization.
	Name string `json:"name"`

	// Slug is the unique URL-friendly slug identifier for the organization.
	Slug string `json:"slug"`

	Logo string `json:"logo,omitempty"`

	// Metadata holds arbitrary key-value properties associated with the organization.
	Metadata map[string]any `json:"metadata,omitempty"`

	// CreatedAt marks the timestamp when the organization was created.
	CreatedAt time.Time `json:"createdAt"`

	// UpdatedAt marks the timestamp when the organization was last modified.
	UpdatedAt *time.Time `json:"updatedAt,omitempty"`
}

Organization represents a tenant boundary containing members, teams, invitations, and custom roles.

type OrganizationRole

type OrganizationRole struct {
	// ID is the unique role identifier.
	ID string `json:"id"`

	// OrganizationID identifies the parent organization owning the role.
	OrganizationID string `json:"organizationId"`

	// Role is the unique role name within the organization.
	Role string `json:"role"`

	// Permissions maps resource names to lists of granted actions (e.g. "member": ["create", "update"]).
	Permissions map[string][]string `json:"permissions"`

	// CreatedAt marks when the role was created.
	CreatedAt time.Time `json:"createdAt"`

	// UpdatedAt marks when the role was last updated.
	UpdatedAt *time.Time `json:"updatedAt,omitempty"`
}

OrganizationRole represents a dynamic, organization-scoped custom role and its permission matrix.

type Permissions

type Permissions map[string][]string

Permissions maps resource identifiers to lists of granted actions (e.g. "member": ["create", "update"]).

func ClonePermissions

func ClonePermissions(p Permissions) Permissions

ClonePermissions creates a deep copy of a Permissions map.

func MergePermissions

func MergePermissions(dst, src Permissions) Permissions

MergePermissions combines source permissions into destination permissions without duplicates.

type Plugin

type Plugin struct {
	// contains filtered or unexported fields
}

Plugin implements multi-tenancy, member, team, and invitation management capabilities.

func New

func New(repo Repository, opts ...Option) *Plugin

New creates a new Organization plugin instance configured with a repository and functional options.

func (*Plugin) AcceptInvitation

func (p *Plugin) AcceptInvitation(ctx context.Context, params AcceptInvitationParams) (*AcceptInvitationResult, error)

AcceptInvitation accepts an active pending invitation, creates a new membership record, assigns team if specified, and marks the invitation accepted.

func (*Plugin) AddMember

func (p *Plugin) AddMember(ctx context.Context, params AddMemberParams) (*AddMemberResult, error)

AddMember adds a user as a member to an organization with a specified role after checking membership limits and RBAC permissions.

func (*Plugin) AddTeamMember

func (p *Plugin) AddTeamMember(ctx context.Context, params AddTeamMemberParams) (*AddTeamMemberResult, error)

AddTeamMember adds an existing organization member to a team after checking team member limits.

func (*Plugin) CancelInvitation

func (p *Plugin) CancelInvitation(ctx context.Context, params CancelInvitationParams) (*CancelInvitationResult, error)

CancelInvitation cancels a pending invitation after verifying user cancellation permissions.

func (*Plugin) CheckPermission

func (p *Plugin) CheckPermission(ctx context.Context, orgID, userRole string, required Permissions) (bool, error)

CheckPermission evaluates whether a user role possesses all required permissions in an organization.

func (*Plugin) CheckSlug

func (p *Plugin) CheckSlug(ctx context.Context, params CheckSlugParams) (*CheckSlugResult, error)

CheckSlug checks whether an organization slug is available for registration.

func (*Plugin) Config

func (p *Plugin) Config() Config

Config returns the active configuration settings of the Organization plugin.

func (*Plugin) CreateInvitation

func (p *Plugin) CreateInvitation(ctx context.Context, params CreateInvitationParams) (*CreateInvitationResult, error)

CreateInvitation generates a new pending invitation for a target email address, enforcing invitation limits, checking authorization permissions, calculating expiration, and optionally dispatching an email notification.

func (*Plugin) CreateOrganization

func (p *Plugin) CreateOrganization(ctx context.Context, params CreateOrganizationParams) (*CreateOrganizationResult, error)

CreateOrganization creates a new tenant organization, registers the creator as its initial owner member, optionally spins up a default team, and marks the organization as active for the user.

func (*Plugin) CreateRole

func (p *Plugin) CreateRole(ctx context.Context, params CreateRoleParams) (*CreateRoleResult, error)

CreateRole creates a new dynamic organization-scoped custom role and its permission matrix.

func (*Plugin) CreateTeam

func (p *Plugin) CreateTeam(ctx context.Context, params CreateTeamParams) (*CreateTeamResult, error)

CreateTeam creates a new team within an organization after checking module enablement, limits, and RBAC permissions.

func (*Plugin) DeleteOrganization

func (p *Plugin) DeleteOrganization(ctx context.Context, params DeleteOrganizationParams) (*DeleteOrganizationResult, error)

DeleteOrganization removes an organization after verifying user delete permissions.

func (*Plugin) DeleteRole

func (p *Plugin) DeleteRole(ctx context.Context, params DeleteRoleParams) (*DeleteRoleResult, error)

DeleteRole deletes a dynamic role from an organization.

func (*Plugin) DeleteTeam

func (p *Plugin) DeleteTeam(ctx context.Context, params DeleteTeamParams) (*DeleteTeamResult, error)

DeleteTeam deletes a team from an organization, enforcing AllowRemovingAllTeams safety.

func (*Plugin) GetActiveMember

func (p *Plugin) GetActiveMember(ctx context.Context, params GetActiveMemberParams) (*GetActiveMemberResult, error)

GetActiveMember retrieves the membership record for a user in their active (or specified) organization.

func (*Plugin) GetActiveMemberRole

func (p *Plugin) GetActiveMemberRole(ctx context.Context, params GetActiveMemberRoleParams) (*GetActiveMemberRoleResult, error)

GetActiveMemberRole retrieves the assigned role name of a user in their active (or specified) organization.

func (*Plugin) GetActiveOrganization

func (p *Plugin) GetActiveOrganization(ctx context.Context, params GetActiveOrganizationParams) (*GetActiveOrganizationResult, error)

GetActiveOrganization retrieves the currently active organization and membership for a user.

func (*Plugin) GetActiveTeam

func (p *Plugin) GetActiveTeam(ctx context.Context, params GetActiveTeamParams) (*GetActiveTeamResult, error)

GetActiveTeam retrieves the currently active team for a user.

func (*Plugin) GetFullOrganization

func (p *Plugin) GetFullOrganization(ctx context.Context, params GetFullOrganizationParams) (*GetFullOrganizationResult, error)

GetFullOrganization retrieves the complete organization details along with members, active invitations, and teams.

func (*Plugin) GetInvitation

func (p *Plugin) GetInvitation(ctx context.Context, params GetInvitationParams) (*GetInvitationResult, error)

GetInvitation retrieves an invitation by its unique identifier.

func (*Plugin) GetMember

func (p *Plugin) GetMember(ctx context.Context, params GetMemberParams) (*GetMemberResult, error)

GetMember retrieves a membership record by organization ID and user ID.

func (*Plugin) GetOrganization

func (p *Plugin) GetOrganization(ctx context.Context, params GetOrganizationParams) (*GetOrganizationResult, error)

GetOrganization retrieves an organization by its unique identifier.

func (*Plugin) GetOrganizationBySlug

func (p *Plugin) GetOrganizationBySlug(ctx context.Context, params GetOrganizationBySlugParams) (*GetOrganizationBySlugResult, error)

GetOrganizationBySlug retrieves an organization by its URL-friendly slug.

func (*Plugin) GetRole

func (p *Plugin) GetRole(ctx context.Context, params GetRoleParams) (*GetRoleResult, error)

GetRole retrieves a dynamic role by its unique identifier.

func (*Plugin) GetTeam

func (p *Plugin) GetTeam(ctx context.Context, params GetTeamParams) (*GetTeamResult, error)

GetTeam retrieves a team by its unique identifier.

func (*Plugin) HasPermission

func (p *Plugin) HasPermission(ctx context.Context, params HasPermissionParams) (*HasPermissionResult, error)

HasPermission checks whether a specified user or role possesses the required permissions in an organization.

func (*Plugin) ID

func (p *Plugin) ID() string

ID returns the unique identifier for the Organization plugin ("organization").

func (*Plugin) Init

func (p *Plugin) Init(ctx *plugin.Context) error

Init initializes the plugin within the global GoModularAuth context.

func (*Plugin) LeaveOrganization

func (p *Plugin) LeaveOrganization(ctx context.Context, params LeaveOrganizationParams) (*LeaveOrganizationResult, error)

LeaveOrganization allows a user to voluntarily leave an organization, preventing the last owner from leaving without transferring ownership.

func (*Plugin) ListInvitations

func (p *Plugin) ListInvitations(ctx context.Context, params ListInvitationsParams) (*ListInvitationsResult, error)

ListInvitations retrieves all invitations for an organization, optionally filtered by status.

func (*Plugin) ListMembers

func (p *Plugin) ListMembers(ctx context.Context, params ListMembersParams) (*ListMembersResult, error)

ListMembers retrieves a paginated list of members belonging to the specified organization.

func (*Plugin) ListOrganizations

func (p *Plugin) ListOrganizations(ctx context.Context, params ListOrganizationsParams) (*ListOrganizationsResult, error)

ListOrganizations returns all organizations where the specified user is a member.

func (*Plugin) ListRoles

func (p *Plugin) ListRoles(ctx context.Context, params ListRolesParams) (*ListRolesResult, error)

ListRoles retrieves all dynamic roles configured for an organization.

func (*Plugin) ListTeamMembers

func (p *Plugin) ListTeamMembers(ctx context.Context, params ListTeamMembersParams) (*ListTeamMembersResult, error)

ListTeamMembers retrieves all members assigned to a team.

func (*Plugin) ListTeams

func (p *Plugin) ListTeams(ctx context.Context, params ListTeamsParams) (*ListTeamsResult, error)

ListTeams retrieves all teams in an organization or all teams where a user participates.

func (*Plugin) ListUserInvitations

func (p *Plugin) ListUserInvitations(ctx context.Context, params ListUserInvitationsParams) (*ListUserInvitationsResult, error)

ListUserInvitations retrieves all invitations targeted to a given email address.

func (*Plugin) RejectInvitation

func (p *Plugin) RejectInvitation(ctx context.Context, params RejectInvitationParams) (*RejectInvitationResult, error)

RejectInvitation marks a pending invitation as rejected.

func (*Plugin) RemoveMember

func (p *Plugin) RemoveMember(ctx context.Context, params RemoveMemberParams) (*RemoveMemberResult, error)

RemoveMember deletes a user's membership from an organization, enforcing last-owner safety protection.

func (*Plugin) RemoveTeamMember

func (p *Plugin) RemoveTeamMember(ctx context.Context, params RemoveTeamMemberParams) (*RemoveTeamMemberResult, error)

RemoveTeamMember removes a user from a team.

func (*Plugin) Repository

func (p *Plugin) Repository() Repository

Repository returns the underlying storage repository instance.

func (*Plugin) RequireMember added in v0.20.0

func (p *Plugin) RequireMember(headerName ...string) func(next http.Handler) http.Handler

RequireMember returns a net/http middleware handler verifying that the user belongs to the target organization.

func (*Plugin) RequirePermission added in v0.20.0

func (p *Plugin) RequirePermission(requiredPermissions Permissions, headerName ...string) func(next http.Handler) http.Handler

RequirePermission returns a net/http middleware handler verifying organization membership and required permissions.

func (*Plugin) ResolveRolePermissions

func (p *Plugin) ResolveRolePermissions(ctx context.Context, orgID, roleStr string) (Permissions, error)

ResolveRolePermissions collects all permissions granted to a given role string, resolving built-in roles, custom static roles, and dynamic organization roles when enabled. Supports compound roles (e.g. "admin,billing").

func (*Plugin) SetActiveOrganization

func (p *Plugin) SetActiveOrganization(ctx context.Context, params SetActiveOrganizationParams) (*SetActiveOrganizationResult, error)

SetActiveOrganization stores the active organization context for a user in the shared context store.

func (*Plugin) SetActiveTeam

func (p *Plugin) SetActiveTeam(ctx context.Context, params SetActiveTeamParams) (*SetActiveTeamResult, error)

SetActiveTeam stores the active team context for a user in the shared context store.

func (*Plugin) UpdateMemberRole

func (p *Plugin) UpdateMemberRole(ctx context.Context, params UpdateMemberRoleParams) (*UpdateMemberRoleResult, error)

UpdateMemberRole updates the role assigned to a member, enforcing last-owner safety protection.

func (*Plugin) UpdateOrganization

func (p *Plugin) UpdateOrganization(ctx context.Context, params UpdateOrganizationParams) (*UpdateOrganizationResult, error)

UpdateOrganization modifies properties of an existing organization after verifying user update permissions.

func (*Plugin) UpdateRole

func (p *Plugin) UpdateRole(ctx context.Context, params UpdateRoleParams) (*UpdateRoleResult, error)

UpdateRole updates the name or permissions of an existing dynamic role.

func (*Plugin) UpdateTeam

func (p *Plugin) UpdateTeam(ctx context.Context, params UpdateTeamParams) (*UpdateTeamResult, error)

UpdateTeam modifies properties of an existing team after verifying user permissions.

type RejectInvitationParams

type RejectInvitationParams struct {
	InvitationID string `json:"invitation_id"`
	UserID       string `json:"user_id,omitempty"`
	plugin.ExtraContainer
}

type RejectInvitationResult

type RejectInvitationResult struct {
	Invitation *Invitation `json:"invitation"`
}

type RemoveMemberParams

type RemoveMemberParams struct {
	OrganizationID string `json:"organization_id"`
	UserID         string `json:"user_id"`
	InvokingUserID string `json:"invoking_user_id,omitempty"`
	plugin.ExtraContainer
}

type RemoveMemberResult

type RemoveMemberResult struct {
	Success bool `json:"success"`
}

type RemoveTeamMemberParams

type RemoveTeamMemberParams struct {
	TeamID         string `json:"team_id"`
	UserID         string `json:"user_id"`
	InvokingUserID string `json:"invoking_user_id,omitempty"`
	plugin.ExtraContainer
}

type RemoveTeamMemberResult

type RemoveTeamMemberResult struct {
	Success bool `json:"success"`
}

type Repository

Repository defines the storage contract for persisting and querying organization-related domain entities. It composes domain-specific sub-interfaces: OrgRepository, MemberRepository, InvitationRepository, TeamRepository, and RoleRepository.

Implement this interface on your custom database adapter (e.g. PostgreSQL, MySQL, SQLite, MongoDB, GORM, SurrealDB).

Implementation Example (GORM / database/sql):

type GormOrganizationRepository struct {
	db *gorm.DB
}

func (r *GormOrganizationRepository) GetOrganizationByID(ctx context.Context, id string) (*organization.Organization, error) {
	var org organization.Organization
	if err := r.db.WithContext(ctx).Where("id = ?", id).First(&org).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, organization.ErrOrganizationNotFound
		}
		return nil, err
	}
	return &org, nil
}

type RoleCreateAfterEventPayload

type RoleCreateAfterEventPayload struct {
	Role *OrganizationRole
	plugin.ExtraContainer
}

type RoleCreateBeforeEventPayload

type RoleCreateBeforeEventPayload struct {
	OrganizationID string
	Role           string
	Permissions    map[string][]string
	plugin.ExtraContainer
}

type RoleDeleteAfterEventPayload

type RoleDeleteAfterEventPayload struct {
	RoleID string
	plugin.ExtraContainer
}

type RoleDeleteBeforeEventPayload

type RoleDeleteBeforeEventPayload struct {
	RoleID string
	plugin.ExtraContainer
}

type RoleRepository added in v0.27.2

type RoleRepository interface {
	// CreateRole creates a dynamic custom role within an organization.
	CreateRole(ctx context.Context, role *OrganizationRole) error

	// GetRoleByID retrieves a custom dynamic role by ID.
	GetRoleByID(ctx context.Context, id string) (*OrganizationRole, error)

	// GetRoleByName retrieves a dynamic role by name within an organization.
	GetRoleByName(ctx context.Context, orgID, roleName string) (*OrganizationRole, error)

	// UpdateRole updates dynamic role permissions.
	UpdateRole(ctx context.Context, role *OrganizationRole) error

	// DeleteRole removes a custom dynamic role.
	DeleteRole(ctx context.Context, id string) error

	// ListRolesByOrgID lists all custom dynamic roles defined in an organization.
	ListRolesByOrgID(ctx context.Context, orgID string) ([]*OrganizationRole, error)

	// CountRoles counts custom dynamic roles defined in an organization.
	CountRoles(ctx context.Context, orgID string) (int, error)
}

RoleRepository defines the persistence operations for dynamic custom roles and permissions.

type RoleUpdateAfterEventPayload

type RoleUpdateAfterEventPayload struct {
	Role *OrganizationRole
	plugin.ExtraContainer
}

type RoleUpdateBeforeEventPayload

type RoleUpdateBeforeEventPayload struct {
	RoleID      string
	Role        *string
	Permissions map[string][]string
	plugin.ExtraContainer
}

type SendInvitationEmailFunc

type SendInvitationEmailFunc func(ctx context.Context, data InvitationEmailData) error

SendInvitationEmailFunc defines a delivery callback to dispatch invitation emails via external email services (SMTP, Resend, etc.).

type SetActiveOrganizationParams

type SetActiveOrganizationParams struct {
	UserID         string `json:"user_id"`
	OrganizationID string `json:"organization_id"`
	plugin.ExtraContainer
}

type SetActiveOrganizationResult

type SetActiveOrganizationResult struct {
	Organization *Organization `json:"organization"`
	Member       *Member       `json:"member"`
}

type SetActiveTeamParams

type SetActiveTeamParams struct {
	UserID string `json:"user_id"`
	TeamID string `json:"team_id"`
	plugin.ExtraContainer
}

type SetActiveTeamResult

type SetActiveTeamResult struct {
	Team *Team `json:"team"`
}

type Team

type Team struct {
	// ID is the unique team identifier.
	ID string `json:"id"`

	// OrganizationID identifies the parent organization.
	OrganizationID string `json:"organizationId"`

	// Name is the display name of the team.
	Name string `json:"name"`

	// CreatedAt marks when the team was created.
	CreatedAt time.Time `json:"createdAt"`

	// UpdatedAt marks when the team was last updated.
	UpdatedAt *time.Time `json:"updatedAt,omitempty"`
}

Team represents a sub-unit or squad within an organization.

type TeamCreateAfterEventPayload

type TeamCreateAfterEventPayload struct {
	Team *Team
	plugin.ExtraContainer
}

type TeamCreateBeforeEventPayload

type TeamCreateBeforeEventPayload struct {
	OrganizationID string
	Name           string
	plugin.ExtraContainer
}

type TeamDeleteAfterEventPayload

type TeamDeleteAfterEventPayload struct {
	TeamID string
	plugin.ExtraContainer
}

type TeamDeleteBeforeEventPayload

type TeamDeleteBeforeEventPayload struct {
	TeamID string
	plugin.ExtraContainer
}

type TeamMember

type TeamMember struct {
	// ID is the unique identifier for the team membership record.
	ID string `json:"id"`

	// TeamID identifies the team.
	TeamID string `json:"teamId"`

	// UserID identifies the member user.
	UserID string `json:"userId"`

	// CreatedAt marks when the user joined the team.
	CreatedAt time.Time `json:"createdAt"`
}

TeamMember represents the membership relation connecting a user to a specific team.

type TeamMemberAddAfterEventPayload

type TeamMemberAddAfterEventPayload struct {
	TeamMember *TeamMember
	plugin.ExtraContainer
}

type TeamMemberAddBeforeEventPayload

type TeamMemberAddBeforeEventPayload struct {
	TeamID string
	UserID string
	plugin.ExtraContainer
}

type TeamMemberRemoveAfterEventPayload

type TeamMemberRemoveAfterEventPayload struct {
	TeamID string
	UserID string
	plugin.ExtraContainer
}

type TeamMemberRemoveBeforeEventPayload

type TeamMemberRemoveBeforeEventPayload struct {
	TeamID string
	UserID string
	plugin.ExtraContainer
}

type TeamRepository added in v0.27.2

type TeamRepository interface {
	// CreateTeam creates a sub-team within an organization.
	CreateTeam(ctx context.Context, team *Team) error

	// GetTeamByID retrieves a team by ID.
	GetTeamByID(ctx context.Context, id string) (*Team, error)

	// UpdateTeam updates mutable team attributes.
	UpdateTeam(ctx context.Context, team *Team) error

	// DeleteTeam removes a team and unassigns members.
	DeleteTeam(ctx context.Context, id string) error

	// ListTeamsByOrgID lists all teams belonging to an organization.
	ListTeamsByOrgID(ctx context.Context, orgID string) ([]*Team, error)

	// ListTeamsByUserID lists teams in an organization to which a user belongs.
	ListTeamsByUserID(ctx context.Context, orgID, userID string) ([]*Team, error)

	// CountTeams returns the count of teams in an organization.
	CountTeams(ctx context.Context, orgID string) (int, error)

	// AddTeamMember assigns a user to a team.
	AddTeamMember(ctx context.Context, teamMember *TeamMember) error

	// RemoveTeamMember unassigns a user from a team.
	RemoveTeamMember(ctx context.Context, teamID, userID string) error

	// GetTeamMember retrieves a team member mapping record.
	GetTeamMember(ctx context.Context, teamID, userID string) (*TeamMember, error)

	// ListTeamMembers lists all member assignments for a team.
	ListTeamMembers(ctx context.Context, teamID string) ([]*TeamMember, error)

	// CountTeamMembers counts members assigned to a team.
	CountTeamMembers(ctx context.Context, teamID string) (int, error)
}

TeamRepository defines the persistence operations for organization sub-teams and team memberships.

type TeamSetActiveAfterEventPayload

type TeamSetActiveAfterEventPayload struct {
	UserID string
	TeamID string
	Team   *Team
	plugin.ExtraContainer
}

type TeamSetActiveBeforeEventPayload

type TeamSetActiveBeforeEventPayload struct {
	UserID string
	TeamID string
	plugin.ExtraContainer
}

type TeamUpdateAfterEventPayload

type TeamUpdateAfterEventPayload struct {
	Team *Team
	plugin.ExtraContainer
}

type TeamUpdateBeforeEventPayload

type TeamUpdateBeforeEventPayload struct {
	TeamID string
	Name   string
	plugin.ExtraContainer
}

type UpdateMemberRoleParams

type UpdateMemberRoleParams struct {
	OrganizationID string `json:"organization_id"`
	UserID         string `json:"user_id"`
	Role           string `json:"role"`
	InvokingUserID string `json:"invoking_user_id,omitempty"`
	plugin.ExtraContainer
}

type UpdateMemberRoleResult

type UpdateMemberRoleResult struct {
	Member *Member `json:"member"`
}

type UpdateOrganizationParams

type UpdateOrganizationParams struct {
	OrganizationID string         `json:"organization_id"`
	UserID         string         `json:"user_id,omitempty"`
	Name           *string        `json:"name,omitempty"`
	Slug           *string        `json:"slug,omitempty"`
	Metadata       map[string]any `json:"metadata,omitempty"`
	plugin.ExtraContainer
}

type UpdateOrganizationResult

type UpdateOrganizationResult struct {
	Organization *Organization `json:"organization"`
}

type UpdateRoleParams

type UpdateRoleParams struct {
	RoleID      string              `json:"role_id"`
	UserID      string              `json:"user_id,omitempty"`
	Role        *string             `json:"role,omitempty"`
	Permissions map[string][]string `json:"permissions,omitempty"`
	plugin.ExtraContainer
}

type UpdateRoleResult

type UpdateRoleResult struct {
	Role *OrganizationRole `json:"role"`
}

type UpdateTeamParams

type UpdateTeamParams struct {
	TeamID string `json:"team_id"`
	UserID string `json:"user_id,omitempty"`
	Name   string `json:"name"`
	plugin.ExtraContainer
}

type UpdateTeamResult

type UpdateTeamResult struct {
	Team *Team `json:"team"`
}

type UserInfo

type UserInfo struct {
	// ID is the unique user identifier.
	ID string `json:"id"`

	// Email is the user's primary email address.
	Email string `json:"email"`

	// Name is the user's display name.
	Name string `json:"name"`

	// Image is an optional avatar or profile image URL.
	Image string `json:"image,omitempty"`
}

UserInfo represents enriched user identity information attached to member records.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL