fedbox

package module
v0.0.0-...-463ea8d Latest Latest
Warning

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

Go to latest
Published: Feb 26, 2026 License: MIT Imports: 58 Imported by: 0

README

FedBOX

MIT Licensed Build Status Go Report Card

FedBOX Logo

FedBOX is a simple ActivityPub enabled server. Its goal is to serve as a reference implementation for the rest of the GoActivityPub packages.

It provides the base for some of the common functionality that such a service would require, such as: HTTP handlers and middlewares, storage and filtering etc.

The current iteration can persist data to BoltDB, Badger, SQLite and directly on the file system, but I want to also add support for PostgreSQL.

Features

Support for C2S ActivityPub:
  • Support for content management activities: Create, Update, Delete.
  • Follow, Accept, Reject with actors as objects.
  • Appreciation activities: Like, Dislike.
  • Reaction activities: Block on actors, Flag on objects.
  • Negating content management and appreciation activities using Undo.
  • OAuth2 authentication using the Authorize server.
Support for S2S ActivityPub
  • Support the same operations as the client to server activities.
  • Capabilities of generating and loading HTTP Signatures from requests.
  • WebFinger user discovery using the WebFinger server.

Installation

See the INSTALL file.

Running a server in a production environment

If you want to run a FedBOX instance as part of the wider fediverse you must make sure that it was built with -tags prod or -tags qa in the build command because the development builds of FedBOX are not compatible with public instances due to the fact that the HTTP-Signatures generated are meant to be replayble from other contexts and lack security.

Further reading

If you are interested in using FedBOX from an application developer point of view, make sure to read the Client to Server document, which details how the local flavour of ActivityPub C2S API can be used.

More information about FedBOX and the other packages in the GoActivityPub library can be found on the wiki.

Contact and feedback

If you have problems, questions, ideas or suggestions, please contact us by posting to the discussions mailing list, or on GitHub. If you desire quicker feedback, the mailing list is preferred, as the GitHub issues are not checked very often.

Documentation

Index

Constants

View Source
const AppName = "FedBOX"
View Source
const URISeparator = "\n"

Variables

View Source
var AppVersion = "HEAD"
View Source
var CTLRun = new(CTL)
View Source
var InternalIRI = vocab.IRI("https://fedbox/")

Functions

func ActorClient

func ActorClient(ctl *Base, actor vocab.Item) *client.C

func BootstrapStorage

func BootstrapStorage(conf config.Options, service vocab.Item, l lw.Logger, pair *ap.KeyPair) error

func CacheKey

func CacheKey(fb *FedBOX, auth vocab.Actor, r http.Request) vocab.IRI

CacheKey generates a unique vocab.IRI hash based on its authenticated user and other parameters

func CleanRequestPath

func CleanRequestPath(next http.Handler) http.Handler

func CreateService

func CreateService(ctl *Base, self vocab.Item, pair *ap.KeyPair, pw []byte) (err error)

func Errf

func Errf(out io.Writer, s string, par ...any)

func FedBOXClient

func FedBOXClient(fb *FedBOX) *client.C

func GenerateID

func GenerateID(base vocab.IRI) func(it vocab.Item, col vocab.Item, by vocab.Item) (vocab.ID, error)

GenerateID creates an IRI that can be used to uniquely identify the "it" item, based on the collection "col" and its creator "by"

func HandleActivity

func HandleActivity(fb *FedBOX) processing.ActivityHandlerFn

HandleActivity handles POST requests to an ActivityPub actor's inbox/outbox, based on the CollectionType

func HandleCollection

func HandleCollection(fb *FedBOX) processing.CollectionHandlerFn

HandleCollection serves content from the generic collection end-points that return ActivityPub objects or activities

func HandleItem

func HandleItem(fb *FedBOX) processing.ItemHandlerFn

HandleItem serves content from the following, followers, liked, and likes end-points that returns a single ActivityPub object

func IsProxyURL

func IsProxyURL(i vocab.IRI) bool

func OutItem

func OutItem(it vocab.Item, b io.Writer) error

func OutJSON

func OutJSON(where io.Writer) func(it vocab.Item) error

func OutOfOrderMw

func OutOfOrderMw(f *FedBOX) func(next http.Handler) http.Handler

func OutText

func OutText(where io.Writer) func(it vocab.Item) error

func ProxyURL

func ProxyURL(fb *FedBOX) http.Handler

ProxyURL Endpoint URI so this actor's clients may access remote ActivityStreams objects which require authentication to access. To use this endpoint, the client posts an x-www-form-urlencoded id parameter with the value being the id of the requested ActivityStreams object.

https://www.w3.org/TR/activitypub/#proxyUrl

func ResetStorage

func ResetStorage(conf config.Options, l lw.Logger) error

func Run

func Run(args ...string) error

func ServeFavIcon

func ServeFavIcon() http.HandlerFunc

func ValidateRequest

func ValidateRequest(r *http.Request) (bool, error)

Types

type Accounts

type Accounts struct {
	Export  Export         `cmd:"" help:"Exports accounts metadata."`
	Import  Import         `cmd:"" help:"Imports accounts metadata."`
	GenKeys GenKeys        `cmd:"" help:"Generate public/private key pairs for actors that are missing them."`
	Pass    ChangePassword `cmd:"" help:"Change password for an actor."`
}

type ActorsCmd

type ActorsCmd struct {
	Add AddActorCmd `cmd:"" help:"Adds an ActivityPub actor."`
}

type AddActorCmd

type AddActorCmd struct {
	Type         vocab.ActivityVocabularyType `help:"The type of the ActivityPub actor to add."`
	KeyType      string                       `help:"Type of keys to generate: ${keyTypes}" enum:"${keyTypes}" default:"${defaultKeyType}"`
	AttributedTo vocab.IRI                    `help:"The IRI of the Actor we should use as author."`
	Tags         []string                     `name:"tag" help:"The tag(s) to attach to the actor."`
	Names        []string                     `arg:"" name:"name" help:"The name(s) of the actor."`
}

func (AddActorCmd) Run

func (a AddActorCmd) Run(ctl *Base) error

type AddClient

type AddClient struct {
	RedirectURIs []string `name:"redirect-uri" help:"The redirect URIs for current application"`
}

func (AddClient) Run

func (a AddClient) Run(ctl *Base) error

type AddCmd

type AddCmd struct {
	Type         vocab.ActivityVocabularyType `help:"The type of ActivityPub object(s) to create." default:"${defaultObjectTypes}"`
	Name         string                       `help:"The name of the ActivityPub object(s) to create."`
	AttributedTo string                       `help:"The IRI of the Actor we should use as author"`
	Tag          []string                     `help:"The tag(s) to attach to the object."`
}

func (AddCmd) Run

func (a AddCmd) Run(ctl *Base) error

type AddToken

type AddToken struct {
	Client string `help:"The client to use for generating the token"`
	Actor  string `arg:"" help:"The actor identifier we want to generate the authorization for (ID)"`
}

func (AddToken) Run

func (a AddToken) Run(ctl *Base) error

type Base

type Base struct {
	Conf              config.Options
	Logger            lw.Logger
	Service           vocab.Actor
	ServicePrivateKey crypto.PrivateKey
	Storage           storage.FullStorage
	// contains filtered or unexported fields
}

func InitControl

func InitControl(c *CTL, version string) (*Base, error)

func NewBase

func NewBase(db storage.FullStorage, conf config.Options, l lw.Logger) (*Base, error)

func (*Base) AddActor

func (ctl *Base) AddActor(p *vocab.Actor, author vocab.Actor) (*vocab.Actor, error)

func (*Base) AddClient

func (ctl *Base) AddClient(pw []byte, redirectUris []string, u any) (string, error)

func (*Base) AddObject

func (ctl *Base) AddObject(p *vocab.Object, author vocab.Actor) (*vocab.Object, error)

func (*Base) Bootstrap

func (ctl *Base) Bootstrap(pw []byte, pair *ap.KeyPair) error

func (*Base) CopyObjects

func (ctl *Base) CopyObjects(to vocab.IRI, from ...vocab.IRI) error

func (*Base) DeleteClient

func (ctl *Base) DeleteClient(id string) error

func (*Base) DeleteObjects

func (ctl *Base) DeleteObjects(reason string, inReplyTo []string, ids ...vocab.IRI) error

func (*Base) GenAuthToken

func (ctl *Base) GenAuthToken(clientID, actorIdentifier string, _ any) (string, error)

func (*Base) List

func (ctl *Base) List(iris vocab.IRIs, types ...vocab.ActivityVocabularyType) (vocab.ItemCollection, error)

func (*Base) ListClients

func (ctl *Base) ListClients() ([]osin.Client, error)

func (*Base) LoadLocalActorWithKey

func (ctl *Base) LoadLocalActorWithKey(actorIRI vocab.IRI) (*vocab.Actor, crypto.PrivateKey, error)

func (*Base) LoadServiceActor

func (ctl *Base) LoadServiceActor() error

func (*Base) MoveObjects

func (ctl *Base) MoveObjects(to vocab.IRI, from ...vocab.IRI) error

func (*Base) Saver

func (ctl *Base) Saver(actor *vocab.Actor) processing.P

func (*Base) SendSignalToServer

func (ctl *Base) SendSignalToServer(sig syscall.Signal) func() error

type BootstrapCmd

type BootstrapCmd struct {
	KeyType  string `help:"Type of keys to generate: ${keyTypes}" enum:"${keyTypes}" default:"${defaultKeyType}"`
	Password string `hidden:""`
}

func (BootstrapCmd) Run

func (b BootstrapCmd) Run(ctl *Base) error

type CTL

type CTL struct {
	SSH `embed:""`

	Url     url.URL          `help:"The URL used by the application."`
	Env     env.Type         `enum:"${envTypes}" help:"The environment to use. Expected values: ${envTypes}" default:"${defaultEnv}"`
	Verbose int              `counter:"v" help:"Increase verbosity level from the default associated with the environment settings."`
	Path    string           `path:"" help:"The path for the storage folder or socket" default:"." env:"STORAGE_PATH"`
	Version kong.VersionFlag `short:"V"`

	// Commands
	Run Serve `cmd:"" name:"run" help:"Run the ${name} instance server (version: ${version})" default:"withargs"`
}

type ChangePassword

type ChangePassword struct {
	IRI vocab.IRI `arg:"" optional:"" name:"iri" help:"The actor for which to change the password."`
}

func (ChangePassword) Run

func (c ChangePassword) Run(ctl *Base) error

type Client

type Client struct {
	Add  AddClient `cmd:"" help:"Adds an OAuth2 client."`
	Del  DelClient `cmd:"" help:"Removes an existing OAuth2 client."`
	List LsClient  `cmd:"" help:"Lists existing OAuth2 clients."`
}

type CopyCmd

type CopyCmd struct {
	To   vocab.IRI   `help:"Collection to which to move the objects." required:""`
	IRIs []vocab.IRI `arg:"" name:"iris"`
}

func (CopyCmd) Run

func (c CopyCmd) Run(ctl *Base) error

type DelClient

type DelClient struct {
	Client []string `arg:"" help:"Removes an existing OAuth2 client"`
}

func (DelClient) Run

func (d DelClient) Run(ctl *Base) error

type DeleteCmd

type DeleteCmd struct {
	Reason    string      `help:"The reason why we want to delete the item"`
	InReplyTo []string    `help:"If deletion is a followup on moderation activities"`
	IRIs      []vocab.IRI `arg:"" name:"iris"`
}

func (DeleteCmd) Run

func (d DeleteCmd) Run(ctl *Base) error

type Export

type Export struct{}

func (Export) Run

func (e Export) Run(ctl *Base) error

type ExportCmd

type ExportCmd struct {
	File string `help:"The path where to output the items, if absent it will be printed to stdout."`
}

func (ExportCmd) Run

func (e ExportCmd) Run(ctl *Base) error

type FedBOX

type FedBOX struct {
	*Base

	R chi.Router
	// contains filtered or unexported fields
}

func New

func New(ctl *Base) (*FedBOX, error)

New instantiates a new FedBOX instance

func (*FedBOX) CollectionRoutes

func (f *FedBOX) CollectionRoutes(descend bool) func(chi.Router)

func (*FedBOX) Pause

func (f *FedBOX) Pause() error

func (*FedBOX) Routes

func (f *FedBOX) Routes() func(chi.Router)

func (*FedBOX) Run

func (f *FedBOX) Run(ctx context.Context) error

Run is the wrapper for starting the web-server and handling signals

func (*FedBOX) Stop

func (f *FedBOX) Stop(ctx context.Context) error

Stop

type FixCollections

type FixCollections struct{}

func (FixCollections) Run

func (f FixCollections) Run(ctl *Base) error

type GenKeys

type GenKeys struct {
	Type string      `help:"Type of keys to generate." name:"key-type" enum:"${keyTypes}" default:"${defaultKeyType}"`
	IRIs []vocab.IRI `arg:"" optional:"" name:"iri" help:"Actors for which to generate the keys. Defaults to all actors if missing."`
}

func (GenKeys) Run

func (g GenKeys) Run(ctl *Base) error

type Import

type Import struct {
	Files []*os.File `arg:""`
}

func (Import) Run

func (i Import) Run(ctl *Base) error

type ImportCmd

type ImportCmd struct {
	Base  vocab.IRI  `help:"The base IRI to replace"`
	Files []*os.File `arg:""`
}

func (ImportCmd) Run

func (i ImportCmd) Run(ctl *Base) error

type IndexCmd

type IndexCmd struct{}

func (IndexCmd) Run

func (i IndexCmd) Run(ctl *Base) error

type InfoCmd

type InfoCmd struct {
	IRIs   []vocab.IRI `arg:"" name:"iris"`
	Output string      `help:"The format in which to output the items." enum:"text,json" default:"text"`
}

func (InfoCmd) Run

func (l InfoCmd) Run(ctl *Base) error

type ListCmd

type ListCmd struct {
	Type   []vocab.ActivityVocabularyType `help:"The type of ActivityPub object to list" default:"${defaultObjectTypes}"`
	Output string                         `help:"The format in which to output the items." enum:"text,json" default:"text"`
	IRIs   []vocab.IRI                    `arg:"" name:"iris"`
}

func (ListCmd) Run

func (l ListCmd) Run(ctl *Base) error

type LogFn

type LogFn func(string, ...any)

type LsClient

type LsClient struct{}

func (LsClient) Run

func (l LsClient) Run(ctl *Base) error

type Maintenance

type Maintenance struct{}

func (Maintenance) Run

func (m Maintenance) Run(ctl *Base) error

type MoveCmd

type MoveCmd struct {
	To   vocab.IRI   `help:"Collection to which to move the objects." required:""`
	IRIs []vocab.IRI `arg:"" name:"iris"`
}

func (MoveCmd) Run

func (m MoveCmd) Run(ctl *Base) error

type OAuth

type OAuth struct {
	Client Client `cmd:"" help:"OAuth2 client application management."`
	Token  Token  `cmd:"" help:"OAuth2 authorization token management."`
}

type Pub

type Pub struct {
	Actors ActorsCmd `cmd:"" name:"actor" help:"Actor management helper."`
	Add    AddCmd    `cmd:"" name:"add" help:"Adds a new object."`
	List   ListCmd   `cmd:"" help:"Lists objects."`
	Info   InfoCmd   `cmd:"" help:"Show information about an object."`
	Delete DeleteCmd `cmd:"" help:"Deletes an ActivityPub object."`
	Move   MoveCmd   `cmd:"" help:"Move ActivityPub objects to a new collection."`
	Copy   CopyCmd   `cmd:"" help:"Copy ActivityPub objects."`
	Index  IndexCmd  `cmd:"" help:"Reindex current storage ActivityPub objects."`
	Export ExportCmd `cmd:"" help:"Exports ActivityPub objects."`
	Import ImportCmd `cmd:"" help:"Imports ActivityPub objects."`
}

type Reload

type Reload struct{}

func (Reload) Run

func (m Reload) Run(ctl *Base) error

type ResetCmd

type ResetCmd struct{}

func (ResetCmd) Run

func (b ResetCmd) Run(ctl *Base) error

type SSH

type SSH struct {
	Pub         Pub         `cmd:"" name:"pub" alt:"ap" help:"ActivityPub management helper"`
	OAuth       OAuth       `cmd:"" name:"oauth"`
	Storage     Storage     `cmd:""`
	Accounts    Accounts    `cmd:"" help:"Accounts helper."`
	Maintenance Maintenance `cmd:"" help:"Toggle maintenance mode for the running FedBOX server."`
	Reload      Reload      `cmd:"" help:"Reload the running FedBOX server configuration."`
	Stop        Stop        `cmd:"" help:"Stops the running FedBOX server configuration."`
}

type Serve

type Serve struct {
	Listen    string        `help:"The socket on which to listen" env:"FEDBOX_LISTEN" env:"LISTEN"`
	Wait      time.Duration `help:"The duration for which the server waits for existing connections to finish" default:"${defaultWaitDuration}"`
	Bootstrap bool          `hidden:""`
	Profile   bool          `hidden:""`
}

func (Serve) Run

func (r Serve) Run(ctl *Base) error

type Stop

type Stop struct{}

func (Stop) Run

func (m Stop) Run(ctl *Base) error

type Storage

type Storage struct {
	Type storage.Type `help:"Type of the backend to use. Possible values: ${storageTypes}"`

	Bootstrap      BootstrapCmd   `cmd:"" help:"Bootstrap the storage"`
	Reset          ResetCmd       `cmd:"" help:"Reset an existing storage."`
	FixCollections FixCollections `cmd:"" help:"Fix storage collections."`
}

type Token

type Token struct {
	Add AddToken `cmd:"" help:"Adds an OAuth2 token"`
}

Directories

Path Synopsis
cmd
fedbox command
internal
env

Jump to

Keyboard shortcuts

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