app

package
v0.0.0-...-e28afbe Latest Latest
Warning

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

Go to latest
Published: Oct 25, 2021 License: AGPL-3.0 Imports: 8 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type APCoreConfig

type APCoreConfig interface {
	// Hostname of the application set in the config
	Host() string
	// Clock timezone set in the config
	ClockTimezone() string
	// Schema name of the database (ex: for Postgres)
	Schema() string
}

APCoreConfig allows the application to reuse common fields set in apcore's config.

type Application

type Application interface {
	// CALLS MADE AT DATABASE INIT TIME
	//
	// These calls are made when invoking the "initialize database" command.
	// They are orthogonal to all of the other calls during the life of
	// program execution.
	CreateTables(c context.Context, db Database, apc APCoreConfig, debug bool) error

	// CALLS MADE AT INIT-ADMINISTRATOR TIME
	//
	// These calls are made when invoking the "initialize administrator"
	// command-line command. They are orthogonal to all of the other calls
	// during the life of program execution
	OnCreateAdminUser(c context.Context, userID string, d Database, apc APCoreConfig) error

	// Start is called at the beginning of a server's lifecycle, after
	// configuration processing and after the database connection is opened
	// but before web traffic is being served.
	//
	// If an error is returned, then the startup process fails.
	Start() error
	// Stop is called at the end of a server's lifecycle, after the web
	// servers have stopped serving traffic but before the database is
	// closed.
	//
	// If an error is returned, shutdown continues but an error is reported.
	Stop() error

	// Returns a pointer to the configuration struct used by the specific
	// application. It will be used to save and load from configuration
	// files. This object will be passed to SetConfiguration after it is
	// loaded from file.
	//
	// It is expected the Application will return an object with sane
	// defaults. The object's struct definition may have struct tags
	// supported by gopkg.in/ini.v1 for additional customization. For
	// example, the "comment" struct tag is much appreciated by admins.
	// Also, it is very important that keys to not collide, so prefix your
	// configuration options with a common prefix:
	//
	//     type MyAppConfig struct {
	//         SomeKey string `ini:"my_app_some_key" comment:"Description of this key"`
	//     }
	//
	// This configuration object is intended to be stable for the lifetime
	// of a running application. When the command to "serve" is given, this
	// function is only called once during application initialization.
	//
	// The command to "configure" will append these defaults to the guided
	// flow. Admins will then be able to inspect the file and modify the
	// configuration if desired.
	//
	// However, sane defaults for an application are incredibly important,
	// as the "new" command guides an admin through the creation process
	// all the way to serving without interruption. So have sane defaults!
	NewConfiguration() interface{}
	// Sets the configuration. The parameter's type is the same type that
	// is returned by NewConfiguration. Return an error if the configuration
	// is invalid.
	//
	// Provides a read-only interface for some of APCore's config fields.
	//
	// This configuration object is intended to be stable for the lifetime
	// of a running application. When the command to serve, is given, this
	// function is only called once during application initialization.
	//
	// When debug is true, the binary was invoked with the dev flag.
	SetConfiguration(config interface{}, apcc APCoreConfig, debug bool) error

	// The handler for the application's "404 Not Found" webpage.
	NotFoundHandler(Framework) http.Handler
	// The handler when a request makes an unsupported HTTP method against
	// a URI.
	MethodNotAllowedHandler(Framework) http.Handler
	// The handler for an internal server error.
	InternalServerErrorHandler(Framework) http.Handler
	// The handler for a bad request.
	BadRequestHandler(Framework) http.Handler

	// Web handler for a GET call to the login page.
	//
	// It should render a login page that POSTs to the "/login" endpoint.
	//
	// If the URL contains a query parameter "login_error" with a value of
	// "true", then it should convey to the user that the email or password
	// previously entered was incorrect.
	GetLoginWebHandlerFunc(Framework) http.HandlerFunc
	// Web handler for a GET call to the OAuth2 authorization page.
	//
	// It should render UX that informs the user that the other application
	// is requesting to be authorized as that user to obtain certain scopes.
	//
	// See the OAuth2 RFC 6749 for more information.
	GetAuthWebHandlerFunc(Framework) http.HandlerFunc

	// Web handler for a call to GET an actor's outbox. The framework
	// applies OAuth2 authorizations to fetch a public-only or private
	// snapshot of the outbox, and passes it to this handler function.
	//
	// The builtin ActivityPub handler will use the OAuth authorization.
	//
	// Returning a nil handler is allowed, and doing so results in only
	// ActivityStreams content being served.
	GetOutboxWebHandlerFunc(Framework) func(w http.ResponseWriter, r *http.Request, outbox vocab.ActivityStreamsOrderedCollectionPage)
	// Web handler for a call to GET an actor's followers collection. The
	// framework has no authorization requirements to view a user's
	// followers collection.
	//
	// Also returns for the corresponding AuthorizeFunc handler, which will
	// be applied to both ActivityPub and web requests.
	//
	// Returning a nil handler is allowed, and doing so results in only
	// ActivityStreams content being served. Returning a nil AuthorizeFunc
	// results in public access.
	GetFollowersWebHandlerFunc(Framework) (CollectionPageHandlerFunc, AuthorizeFunc)
	// Web handler for a call to GET an actor's following collection. The
	// framework has no authorization requirements to view a user's
	// following collection.
	//
	// Also returns for the corresponding AuthorizeFunc handler, which will
	// be applied to both ActivityPub and web requests.
	//
	// Returning a nil handler is allowed, and doing so results in only
	// ActivityStreams content being served. Returning a nil AuthorizeFunc
	// results in public access.
	GetFollowingWebHandlerFunc(Framework) (CollectionPageHandlerFunc, AuthorizeFunc)
	// Web handler for a call to GET an actor's liked collection. The
	// framework has no authorization requirements to view a user's
	// liked collection.
	//
	// Also returns for the corresponding AuthorizeFunc handler, which will
	// be applied to both ActivityPub and web requests.
	//
	// Returning a nil handler is allowed, and doing so results in only
	// ActivityStreams content being served. Returning a nil AuthorizeFunc
	// results in public access.
	GetLikedWebHandlerFunc(Framework) (CollectionPageHandlerFunc, AuthorizeFunc)
	// Web handler for a call to GET an actor. The framework has no
	// authorization requirements to view a user, like a profile.
	//
	// Also returns for the corresponding AuthorizeFunc handler, which will
	// be applied to both ActivityPub and web requests.
	//
	// Returning a nil handler is allowed, and doing so results in only
	// ActivityStreams content being served. Returning a nil AuthorizeFunc
	// results in public access.
	GetUserWebHandlerFunc(Framework) (VocabHandlerFunc, AuthorizeFunc)

	// Builds the HTTP and ActivityPub routes specific for this application.
	//
	// The database is provided so custom handlers can access application
	// data directly, allowing clients to create the custom Fediverse
	// behavior their application desires.
	//
	// The Framework provided allows handlers to use common behaviors
	// provided by the apcore server framework.
	//
	// The bulk of typical HTTP application logic is in the handlers created
	// by the Router. The apcore.Router also supports creating routes that
	// process and serve ActivityStreams data, but the processing of the
	// ActivityPub data itself is handled elsewhere in
	// ApplyFederatingCallbacks and/or ApplySocialCallbacks.
	BuildRoutes(r Router, db Database, f Framework) error
	// Paths allows applications to customize endpoints supported by apcore.
	//
	// See the Paths object for the various custom paths and their defaults.
	// Returning a zero-value struct is valid.
	Paths() Paths
	// StaticServingEnabled indicates whether to enable static serving from
	// a local folder. Only takes effect during server startup, dynamically
	// changing the return value during runtime has no effect.
	StaticServingEnabled() bool

	// NewIDPath creates a new id IRI path component for the content being
	// created.
	//
	// A peer making a GET request to this path on this server should then
	// serve the ActivityPub value provided in this call. For example:
	//   "/notes/abcd0123-4567-890a-bcd0-1234567890ab"
	//
	// Ensure the route returned by NewIDPath will be servable by a handler
	// created in the BuildRoutes call.
	NewIDPath(c context.Context, t vocab.Type) (path string, err error)

	// ScopePermitsPrivateGetInbox determines if an OAuth token scope
	// permits the bearer to view private (non-Public) messages in an
	// actor's inbox.
	ScopePermitsPrivateGetInbox(scope string) (permitted bool, err error)
	// ScopePermitsPrivateGetOutbox determines if an OAuth token scope
	// permits the bearer to view private (non-Public) messages in an
	// actor's outbox.
	ScopePermitsPrivateGetOutbox(scope string) (permitted bool, err error)

	// DefaultUserPreferences returns an application-specific preferences
	// struct to be serialized into JSON and used as initial user app
	// preferences.
	DefaultUserPreferences() interface{}
	// DefaultUserPrivileges returns an application-specific privileges
	// struct to be serialized into JSON and used as initial user app
	// privileges.
	DefaultUserPrivileges() interface{}
	// DefaultAdminPrivileges returns an application-specific privileges
	// struct to be serialized into JSON and used as initial user app
	// privileges for new admins.
	DefaultAdminPrivileges() interface{}

	// Information about this application's software. This will be shown at
	// the command line and used for NodeInfo statistics, as well as for
	// user agent information.
	Software() Software
}

Application is an ActivityPub application built on top of apcore's infrastructure. Your application must also implement C2SApplication, S2SApplication, or both interfaces in order to gain the benefits of federating using ActivityPub's Social or Federating Protocols.

type AuthorizeFunc

type AuthorizeFunc func(c context.Context, w http.ResponseWriter, r *http.Request, db Database) (permit bool, err error)

type C2SApplication

type C2SApplication interface {
	// ScopePermitsPostOutbox determines if an OAuth token scope permits the
	// bearer to post to an actor's outbox.
	ScopePermitsPostOutbox(scope string) (permitted bool, err error)

	// ApplySocialCallbacks injects ActivityPub specific behaviors for
	// social, or C2S, data.
	//
	// Additional behavior for out-of-the-box supported types, such as the
	// Create type, can be set by directly defining a function on the
	// callback passed in:
	//
	//     func (m *myImpl) ApplySocialCallbacks(swc *pub.SocialWrappedCallbacks) (others []interface{}) {
	//       swc.Create = func(c context.Context, as vocab.ActivityStreamsCreate) error {
	//         // Additional application behavior for the Create activity.
	//       }
	//     }
	//
	// To use less common types that do no have out-of-the-box behavior,
	// such as the Listen type, return the functions in `others` that
	// implement the behavior. The functions in `others` must be in the
	// form:
	//
	//     func(c context.Context, as vocab.ActivityStreamsListen) error {
	//       // Application behavior for the Listen activity.
	//     }
	//
	// Caution: returning an out-of-the-box supported type in `others` will
	// override the framework-provided default behavior for that type. For
	// example, the "Create" behavior's default behavior of creating
	// ActivityStreams types in the database can be overridden by:
	//
	//     func (m *myImpl) ApplySocialCallbacks(swc *pub.SocialWrappedCallbacks) (others []interface{}) {
	//       others = []interface{}{
	//         func(c context.Context, as vocab.ActivityStreamsCreate) error {
	//           // New behavior for the Create activity that overrides the
	//           // framework provided defaults.
	//         },
	//       }
	//       return
	//     }
	ApplySocialCallbacks(swc *pub.SocialWrappedCallbacks) (others []interface{})
}

C2SApplication is an Application with additional methods required to support the C2S, or Social, ActivityPub protocol.

type Database

type Database interface {
	Begin() TxBuilder
}

type Framework

type Framework interface {
	Context(r *http.Request) context.Context

	UserIRI(userUUID paths.UUID) *url.URL

	// CreateUser creates a new unprivileged user with the given username,
	// email, and password.
	//
	// If an error is returned, it can be checked using IsNotUniqueUsername
	// and IsNotUniqueEmail to show the error to the user.
	CreateUser(c context.Context, username, email, password string) (userID string, err error)

	// IsNotUniqueUsername returns true if the error returned from
	// CreateUser is due to the username not being unique.
	IsNotUniqueUsername(error) bool

	// IsNotUniqueEmail returns true if the error returned from CreateUser
	// is due to the email not being unique.
	IsNotUniqueEmail(error) bool

	// Validate attempts to obtain and validate the OAuth token or first
	// party credential in the request. This can be called in your handlers
	// at request-handing time.
	//
	// If an error is returned, both the token and authentication values
	// should be ignored.
	//
	// TODO: Scopes
	Validate(w http.ResponseWriter, r *http.Request) (userID paths.UUID, authenticated bool, err error)

	// Send will send an Activity or Object on behalf of the user.
	//
	// Note that a new ID is not needed on the activity and/or objects that
	// are being sent; they will be generated as needed.
	//
	// Calling Send when federation is disabled results in an error.
	Send(c context.Context, userID paths.UUID, toSend vocab.Type) error

	// SendAcceptFollow accepts the provided Follow on behalf of the user.
	//
	// Calling SendAcceptFollow when federation is disabled results in an
	// error.
	SendAcceptFollow(c context.Context, userID paths.UUID, followIRI *url.URL) error

	// SendRejectFollow rejects the provided Follow on behalf of the user.
	//
	// Calling SendRejectFollow when federation is disabled results in an
	// error.
	SendRejectFollow(c context.Context, userID paths.UUID, followIRI *url.URL) error

	Session(r *http.Request) (Session, error)

	// TODO: Determine if we need this.
	GetByIRI(c context.Context, id *url.URL) (vocab.Type, error)

	// Given a user ID, retrieves all follow requests that have not yet been
	// Accepted nor Rejected.
	OpenFollowRequests(c context.Context, userID paths.UUID) ([]vocab.ActivityStreamsFollow, error)

	// GetPrivileges accepts a pointer to an appPrivileges struct to read
	// from the database for the given user, and also returns whether that
	// user is an admin.
	GetPrivileges(c context.Context, userID paths.UUID, appPrivileges interface{}) (admin bool, err error)
	// SetPrivileges sets the given application privileges and admin status
	// for the given user.
	SetPrivileges(c context.Context, userID paths.UUID, admin bool, appPrivileges interface{}) error
}

Framework provides request-time hooks for use in handlers.

type Paths

type Paths struct {
	GetLogin            string
	PostLogin           string
	GetLogout           string
	GetOAuth2Authorize  string
	PostOAuth2Authorize string
	RedirectToHomepage  func(string) string
	RedirectToLogin     func(string) string
}

Paths is a set of endpoints for apcore handlers provided out of the box. It allows applications to override defaults, for example in case localization where "/login" can instead be "/{locale}/login".

The Redirect fields are functions. They accept the current path and can return a corresponding path. For example, when redirecting to the homepage in a locale usecase, it may be passed "/de-DE/login" which means the function then returns "/de-DE".

A zero-value struct is valid and uses apcore defaults.

func (Paths) GetLoginPath

func (p Paths) GetLoginPath() string

func (Paths) GetLogoutPath

func (p Paths) GetLogoutPath() string

func (Paths) GetOAuth2AuthorizePath

func (p Paths) GetOAuth2AuthorizePath() string

func (Paths) PostLoginPath

func (p Paths) PostLoginPath() string

func (Paths) PostOAuth2AuthorizePath

func (p Paths) PostOAuth2AuthorizePath() string

func (Paths) RedirectToHomepagePath

func (p Paths) RedirectToHomepagePath(currentPath string) string

func (Paths) RedirectToLoginPath

func (p Paths) RedirectToLoginPath(currentPath string) string

type Route

type Route interface {
	ActivityPubOnlyHandleFunc(path string, authFn AuthorizeFunc) Route
	ActivityPubAndWebHandleFunc(path string, authFn AuthorizeFunc, f func(http.ResponseWriter, *http.Request)) Route
	HandleAuthorizationRequest(path string) Route
	HandleAccessTokenRequest(path string) Route
	WebOnlyHandler(path string, handler http.Handler) Route
	WebOnlyHandlerFunc(path string, f func(http.ResponseWriter, *http.Request)) Route
	Handler(handler http.Handler) Route
	HandlerFunc(f func(http.ResponseWriter, *http.Request)) Route
	Headers(pairs ...string) Route
	Host(tpl string) Route
	Methods(methods ...string) Route
	Name(name string) Route
	Path(tpl string) Route
	PathPrefix(tpl string) Route
	Queries(pairs ...string) Route
	Schemes(schemes ...string) Route
	Subrouter() Router
}

type Router

type Router interface {
	ActivityPubOnlyHandleFunc(path string, authFn AuthorizeFunc) Route
	ActivityPubAndWebHandleFunc(path string, authFn AuthorizeFunc, f func(http.ResponseWriter, *http.Request)) Route
	HandleAuthorizationRequest(path string) Route
	HandleAccessTokenRequest(path string) Route
	Get(name string) Route
	WebOnlyHandle(path string, handler http.Handler) Route
	WebOnlyHandleFunc(path string, f func(http.ResponseWriter, *http.Request)) Route
	Handle(path string, handler http.Handler) Route
	HandleFunc(path string, f func(http.ResponseWriter, *http.Request)) Route
	Headers(pairs ...string) Route
	Host(tpl string) Route
	Methods(methods ...string) Route
	Name(name string) Route
	NewRoute() Route
	Path(tpl string) Route
	PathPrefix(tpl string) Route
	Queries(pairs ...string) Route
	Schemes(schemes ...string) Route
	Use(mwf ...mux.MiddlewareFunc)
	Walk(walkFn mux.WalkFunc) error
}

type S2SApplication

type S2SApplication interface {
	// Web handler for a call to GET an actor's inbox. The framework applies
	// OAuth2 authorizations to fetch a public-only or private snapshot of
	// the inbox, and passes it into this handler function.
	//
	// The builtin ActivityPub handler will use the OAuth authorization.
	//
	// Returning a nil handler is allowed, and doing so results in only
	// ActivityStreams content being served.
	GetInboxWebHandlerFunc(Framework) func(w http.ResponseWriter, r *http.Request, outbox vocab.ActivityStreamsOrderedCollectionPage)

	// ApplyFederatingCallbacks injects ActivityPub specific behaviors for
	// federated data.
	//
	// Additional behavior for out-of-the-box supported types, such as the
	// Create type, can be set by directly defining a function on the
	// callback passed in:
	//
	//     func (m *myImpl) ApplyFederatingCallbacks(fwc *pub.FederatingWrappedCallbacks) (others []interface{}) {
	//       fwc.Create = func(c context.Context, as vocab.ActivityStreamsCreate) error {
	//         // Additional application behavior for the Create activity.
	//       }
	//     }
	//
	// To use less common types that do no have out-of-the-box behavior,
	// such as the Listen type, return the functions in `others` that
	// implement the behavior. The functions in `others` must be in the
	// form:
	//
	//     func(c context.Context, as vocab.ActivityStreamsListen) error {
	//       // Application behavior for the Listen activity.
	//     }
	//
	// Caution: returning an out-of-the-box supported type in `others` will
	// override the framework-provided default behavior for that type. For
	// example, the "Create" behavior's default behavior of creating
	// ActivityStreams types in the database can be overridden by:
	//
	//     func (m *myImpl) ApplyFederatingCallbacks(fwc *pub.FederatingWrappedCallbacks) (others []interface{}) {
	//       others = []interface{}{
	//         func(c context.Context, as vocab.ActivityStreamsCreate) error {
	//           // New behavior for the Create activity that overrides the
	//           // framework provided defaults.
	//         },
	//       }
	//       return
	//     }
	//
	// Note: The `OnFollow` value will already be populated by the user's
	// preferred behavior upon receiving a Follow request.
	ApplyFederatingCallbacks(fwc *pub.FederatingWrappedCallbacks) (others []interface{})
}

S2SApplication is an Application with the additional methods required to support the S2S, or Federating, ActivityPub protocol.

type Session

type Session interface {
	UserID() (string, error)
	Set(string, interface{})
	Get(string) (interface{}, bool)
	Has(string) bool
	Delete(string)
	Save(*http.Request, http.ResponseWriter) error
}

type SingleRow

type SingleRow interface {
	Scan(dest ...interface{}) error
}

type Software

type Software struct {
	Name         string
	UserAgent    string
	MajorVersion int
	MinorVersion int
	PatchVersion int
	Repository   string
}

func (Software) String

func (s Software) String() string

func (Software) Version

func (s Software) Version() string

type TxBuilder

type TxBuilder interface {
	QueryOneRow(sql string, cb func(r SingleRow) error, args ...interface{})
	Query(sql string, cb func(r SingleRow) error, args ...interface{})
	ExecOneRow(sql string, args ...interface{})
	Exec(sql string, args ...interface{})
	Do(c context.Context) error
}

type VocabHandlerFunc

type VocabHandlerFunc func(http.ResponseWriter, *http.Request, vocab.Type)

Jump to

Keyboard shortcuts

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