ab

package module
v0.0.0-...-9082c2d Latest Latest
Warning

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

Go to latest
Published: Oct 2, 2016 License: Apache-2.0 Imports: 41 Imported by: 2

README

Alien Bunny

Web development platform.

Quick start

To install:

go get -u gitlab.com/tamasd/ab/cmd/abt

To install the frontend:

npm install --save abjs

Alternatively, if you want to work on the development version, use npm link:

cd $GOPATH/gitlab.com/tamasd/ab/js
npm link
cd $YOUR_PROJECT
npm link abjs

To have full universal JS support, see the V8 subproject.

See examples and more information at the project website.

Requirements

  • Go 1.7.
  • Built-in functionalities using PostgreSQL require PostgreSQL 9.5 or newer.
  • Frontend components and the scaffolded application base require NPM 3+.

The abt command

The abt command is a helper tool for the development. Subcommands:

  • watch: starts a proxy that builds and reruns your application when you save a file.
  • gensecret: generates a secret key. Useful for generating cookie secrets.
  • decrypt: decrypts a string with the util package

Contributing

Feel free to open an issue / pull request for discussion, feature request or bug report.

build status coverage report

Documentation

Overview

Package ab is the main package of the Alien Bunny web development kit.

This package contains the server and the middlewares of the framework. If you want to get started, you probably want to take a look at Hop and PetBunny.

The lowest level component is the Server component. It is a wrapper on the top of httprouter that adds middlewares along with a few useful features. On the server you can configure Services. Services are logical units of endpoints that share a piece of schema. On the top of the services, there are resources. Resources are CRUD endpoints. There are delegates and event handlers that help augmenting the functionality of the ResourceController.

Entities are a pointer to a struct that can be stored in a database. EntityController automatically does CRUD on entities, and the operations can be customized with delegates and event handlers.

EntityResource combines the EntityController and the ResourceController to easily expose an entity through API endpoints.

Quick and dirty usage:

func main() {
	ab.Hop(func(cfg *viper.Viper, s *ab.Server) error {
		ec := ab.NewEntityController(s.GetDBConnection())
		ec.Add(&Content{}, contentEntityDelegate{})

		res := ab.EntityResource(ec, &Content{}, ab.EntityResourceConfig{
			DisableList: true,
			DisablePost: true,
			DisablePut: true,
			DisableDelete: true,
		})

		s.RegisterService(res)

		return nil
	}, nil)
}

Index

Constants

This section is empty.

Variables

View Source
var (
	OtherForegroundColor   = "fdf6e3"
	WarningForegroundColor = "fdf6e3"
	ErrorForegroundColor   = "fdf6e3"
	OtherBackgroundColor   = "268bd2"
	WarningBackgroundColor = "b58900"
	ErrorBackgroundColor   = "dc322f"
)

Color codes for HTML error pages

View Source
var (
	MalformedCookieError             = errors.New("malformed cookie")
	SignatureVerificationFailedError = errors.New("signature verification failed")
)
View Source
var Decoders = map[string]func(body io.Reader, v interface{}) error{
	"application/json": JSONDecoder,
	"application/xml":  XMLDecoder,
	"text/xml":         XMLDecoder,
	"text/csv":         CSVDecoder,
}

POST data decoders. The key is the content type, the value is a decoder that decodes the contents of the Reader into v.

View Source
var EntityDBTypeMap = map[string]string{
	"string":  "character varying",
	"int64":   "int8",
	"int32":   "int4",
	"int16":   "int2",
	"int":     "int",
	"float32": "float4",
	"float64": "float8",
	"bool":    "bool",
	"Time":    "timestamp with time zone",
	"struct":  "jsonb",
}

EntityDBTypeMap maps Go types to PostgreSQL types

View Source
var ErrNoEndpoints = errors.New("no endpoints are enabled for this resource")
View Source
var ErrorPage = template.Must(template.New("ErrorPage").Parse(`<!DOCTYPE HTML>
<html>
<head>
	<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
	<meta charset="utf8" />
	<title>Error</title>
	<style type="text/css">
		body {
			background-color: #{{.BackgroundColor}};
			color: #{{.ForegroundColor}};
		}
	</style>
</head>
	<body>
		<h1>HTTP Error {{.Code}}</h1>
		<p>{{.Message}}</p>
		<hr/>
		{{if .RequestID}}<p> Request ID: {{.RequestID}} </p>
		<hr/>{{end}}
		<pre>{{.Logs}}</pre>
	</body>
</html>
`))

ErrorPage is the default HTML template for the standard HTML error page.

View Source
var JSONPrefix = true

JSONPrefix is a global switch for the ")]}',\n" JSON response prefix.

This prefix increases security for browser-based applications, but requires extra support on the client side.

View Source
var NoDecoderErr = errors.New("no decoder found for the request content type")

Functions

func CSRFGetMiddleware

func CSRFGetMiddleware(urlParam string) func(http.Handler) http.Handler

CSRFGetMiddleware checks the CSRF token in the urlParam URL parameter.

This is useful if you want CSRF protection in a GET request. For example, this middleware is used on the auth service's login/logout endpoints. Adding this to the server is discouraged. The middlware should be used only on the individual handlers.

func CSRFMiddleware

func CSRFMiddleware(next http.Handler) http.Handler

CSRFMiddleware enforces the correct X-CSRF-Token header on all POST, PUT, DELETE, PATCH requests.

To obtain a token, use CSRFTokenHandler on a path.

func CSRFTokenHandler

func CSRFTokenHandler(w http.ResponseWriter, r *http.Request)

CSRFTokenHandler returns the valid csrf token for the current client.

The return format is either JSON or text.

func CSVDecoder

func CSVDecoder(body io.Reader, v interface{}) error

CSVDecoder decodes the request body using the built-in CSV reader into v.

v must be *[][]string

func ConstraintErrorConverter

func ConstraintErrorConverter(msgMap map[string]string) func(*pq.Error) VerboseError

ConstraintErrorConverter converts a constraint violation error into a user-friendly message.

func ConstraintExists

func ConstraintExists(db DB, constraint string) bool

ConstraintExists checks if a constraint exists in the database

func ConvertDBError

func ConvertDBError(err error, conv func(*pq.Error) VerboseError) error

ConvertDBError converts an error with conv if that error is *pq.Error.

Useful when processing database errors (e.g. constraint violations), so the user can get a nice error message.

func DBErrorToVerboseString

func DBErrorToVerboseString(err *pq.Error) string

DBErrorToVerboseString is a helper function that converts a *pq.Error into a detailed string.

func DBMiddleware

func DBMiddleware(connectString string, maxIdleConnections, maxOpenConnections int) (func(http.Handler) http.Handler, *sql.DB)

DBMiddleware manages the database connection. Currently only PostgreSQL is supported.

Automatically added to the server with PetBunny if the server has a connect string.

func Decode

func Decode(r *http.Request, v interface{}) error

Decode decodes a request body into v. After decoding, it closes the body.

This function considers only the Content-Type header, and requires its presence. See the Decoders variable for more information.

func DefaultLoggerMiddleware

func DefaultLoggerMiddleware(level log.LogLevel) func(http.Handler) http.Handler

DefaultLoggerMiddleware creates created a LoggerMiddleware with the recommended settings.

func ErrorHandlerMiddleware

func ErrorHandlerMiddleware(displayErrors bool) func(http.Handler) http.Handler

ErrorHandlerMiddleware injects an ErrorHandler into the request context, and then recovers if the ErrorHandler paniced.

The caller of the function should also supply a logger that will log the errors. The displayErrors sends the error messages to the user. This is useful in a development environment.

This middleware is automatically added to the Server with PetBunny.

func Fail

func Fail(code int, err error)

Calls HandleError on the Error object inside the request context.

func GetCSRFToken

func GetCSRFToken(r *http.Request) string

GetCSRFToken returns the CSRF token for the current session.

If the token is not exists, the function generates one and places it inside the session.

func GetParams

func GetParams(r *http.Request) httprouter.Params

GetParams returns the path parameter values from the request.

func GetRequestID

func GetRequestID(r *http.Request) string

GetRequestID returns the current request's request id.

func HSTSMiddleware

func HSTSMiddleware(config HSTSConfig) func(http.Handler) http.Handler

HSTSMiddleware adds HTTP Strict Transport Security headers to the responses.

func HTTPSRedirectServer

func HTTPSRedirectServer(httpsAddr, httpAddr string) error

HTTPSRedirectServe redirects HTTP requests to HTTPS.

httpsAddr and httpAddr must be host:port format, where the port can be omitted.

func Hop

func Hop(configure func(cfg *viper.Viper, s *Server) error, cfg *viper.Viper, topMiddlewares ...func(http.Handler) http.Handler)

Hop sets up and starts a server.

This function is a wrapper around PetBunny(). The cfg parameter can be nil, in that case a new one will be created.

Extra viper values:

- secret: sets util.SetKey(). Must be a 32 byte hex-encoded string.

func JSONDecoder

func JSONDecoder(body io.Reader, v interface{}) error

JSONDecoder decodes the request body using the built-in JSON decoder into v.

func LogTrace

func LogTrace(r *http.Request) log.Logger

LogTrace returns the trace level logger from the request context.

func LogUser

func LogUser(r *http.Request) log.Logger

LogUser returns the user level logger from the request context.

func LogVerbose

func LogVerbose(r *http.Request) log.Logger

LogVerbose returns the verbose level logger from the request context.

func LoggerMiddleware

func LoggerMiddleware(level log.LogLevel, userLogFactory, verboseLogFactory, traceLogFactory func(w io.Writer) log.Logger, lw io.Writer) func(http.Handler) http.Handler

LoggerMiddleware injects a logger and a per request log buffer into the request context.

func MaybeFail

func MaybeFail(code int, err error, excludedErrors ...error)

Calls Fail() if err is not nil and not any of excludedErrors.

func MustDecode

func MustDecode(r *http.Request, v interface{})

MustDecode is the same as Decode(), but it panics instead of returning an error.

When using the kit with the recommended settings, this method is recommended instead of Decode(), because the panic will get caught by the error handler middleware.

func Pager

func Pager(r *http.Request, limit int) int

Pager is a function that implements pagination for listing endpoints.

It extracts the "page" query from the url, and returns the offset to that given page. The parameter limit specifies the number of elements on a given page.

func RedirectDestination

func RedirectDestination(r *http.Request) string

RedirectDestination constucts an URL to the redirect destination.

The redirect destination is read from the destination URL parameter.

func RedirectServer

func RedirectServer(addr, redirectAddr, certFile, keyFile string) error

RedirectServer sets up and starts a http server that redirects all requests to redirectAddr.

func RendererMiddleware

func RendererMiddleware(next http.Handler) http.Handler

RendererMiddleware is the middleware for the Render API.

This middleware is automatically added with PetBunny.

This changes the behavior of the ResponseWriter in the following middlewares and the page handler. The ResponseWriter's WriteHeader() method will not write the headers, just sets the Code attribute of the Renderer struct in the page context. This hack is necessary, because else a middleware could write the headers before the Renderer. Given the default configuration, the session middleware comes after the RendererMiddleware (so the session middleware has a chance to set its session cookie), and the session middleware always calls WriteHeader(). See the rendererResponseWriter.WriteHeader() method's documentation for more details.

func RequestIDMiddleware

func RequestIDMiddleware(next http.Handler) http.Handler

RequestIDMiddleware generates a request id for every request. Useful for logging.

func RequestLoggerMiddleware

func RequestLoggerMiddleware(lw io.Writer) func(http.Handler) http.Handler

RequestLoggerMiddleware logs request data (method, length, path).

func RequestLogs

func RequestLogs(r *http.Request) string

RequestLogs returns the contents of the log buffer of the request.

func RestrictAddressMiddleware

func RestrictAddressMiddleware(addresses ...string) func(http.Handler) http.Handler

RestrictAddressMiddleware restricts access based on the IP address of the client.

Only IP addresses in the given CIDR address ranges will be allowed.

func RestrictPrivateAddressMiddleware

func RestrictPrivateAddressMiddleware() func(http.Handler) http.Handler

RestrictPrivateAddressMiddleware restricts access to private addresses.

func SessionMiddleware

func SessionMiddleware(prefix string, key SecretKey, cookieURL *url.URL, expiresAfter time.Duration) func(http.Handler) http.Handler

SessionMiddleware creates a session middleware.

The prefix is an optional prefix for the cookie name. The cookie name after the prefix is "_SESSION". The key holds the secret key to sign and verify the cookies. The cookie URL determines the domain and the path parts of the HTTP cookie that will be set. It can be nil. If the cookie URL starts with https://, then the cookie will be forced to work only on HTTPS. The expiresAfter sets a duration for the cookies to expire.

func SetContext

func SetContext(r *http.Request, key, value interface{}) *http.Request

SetContext sets a value in the context of *http.Request, and returns a new one with the updated context.

func TableExists

func TableExists(db DB, table string) bool

TableExists checks if a table exists in the database.

func TransactionMiddleware

func TransactionMiddleware(next http.Handler) http.Handler

TransactionMiddleware turns the DB connection in the context into a transaction.

The transaction gets committed automatically, or rolled back if an error occours.

func XMLDecoder

func XMLDecoder(body io.Reader, v interface{}) error

XMLDecoder decodes the request body using the built-in XML decoder into v.

Types

type DB

type DB interface {
	Exec(string, ...interface{}) (sql.Result, error)
	Query(string, ...interface{}) (*sql.Rows, error)
	QueryRow(string, ...interface{}) *sql.Row
	Prepare(string) (*sql.Stmt, error)
}

DB is an abstraction over *sql.DB and *sql.Tx

func GetDB

func GetDB(r *http.Request) DB

GetDB returns DB from the request context.

type DefaultResourceFormatter

type DefaultResourceFormatter struct {
}

DefaultResourceFormatter is a simple formatter that formats resources as HAL+JSON, JSON and XML.

func (*DefaultResourceFormatter) FormatMulti

func (f *DefaultResourceFormatter) FormatMulti(res ResourceList, r *Renderer)

func (*DefaultResourceFormatter) FormatSingle

func (f *DefaultResourceFormatter) FormatSingle(res Resource, r *Renderer)

type EndpointLinker

type EndpointLinker interface {
	Links() map[string][]interface{}
	Curies() []HALCurie
}

EndpointLinker adds links and curies to an endpoint.

If an entity implements this, HAL data will be added to the response with the HALJSON Render type.

type Entity

type Entity interface {
	GetID() string
}

Entity is the interface for the entities.

Types implementing the Entity interface are expected to be pointers to structs.

type EntityController

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

EntityController manages CRUD on entities.

func NewEntityController

func NewEntityController(db DB) *EntityController

NewEntityController initializes an EntityController with a default database connection.

func (*EntityController) Add

Adds an entity type to the controller.

The entity parameter should be an empty entity.

func (*EntityController) AddDeleteEvent

func (ec *EntityController) AddDeleteEvent(evt ...EntityWriteEvent) *EntityController

AddDeleteEvent adds a delete event handler to the entity controller.

func (*EntityController) AddInsertEvent

func (ec *EntityController) AddInsertEvent(evt ...EntityWriteEvent) *EntityController

AddInsertEvent adds an insert event handler to the entity controller.

func (*EntityController) AddLoadEvent

func (ec *EntityController) AddLoadEvent(evt ...EntityReadEvent) *EntityController

AddLoadEvent adds a load event handler to the entity controller.

func (*EntityController) AddUpdateEvent

func (ec *EntityController) AddUpdateEvent(evt ...EntityWriteEvent) *EntityController

AddUpdateEvent adds an update event handler to the entity controller.

func (*EntityController) Delete

func (ec *EntityController) Delete(db DB, e Entity) error

Delete deletes an entity from the database.

func (*EntityController) Empty

func (ec *EntityController) Empty(name string) Entity

Empty creates a new empty value of the given entity.

func (*EntityController) FieldList

func (ec *EntityController) FieldList(name string) string

FieldList returns a comma-separated list of the columns for the given entity.

func (*EntityController) Insert

func (ec *EntityController) Insert(db DB, e Entity) error

Insert inserts an entity into the database.

func (*EntityController) Load

func (ec *EntityController) Load(db DB, entityType string, keys ...interface{}) (Entity, error)

Load loads the given entity type for the given keys.

func (*EntityController) LoadFromQuery

func (ec *EntityController) LoadFromQuery(db DB, entityType string, query string, args ...interface{}) ([]Entity, error)

LoadFromQuery loads entities from a query.

The entity is stored in the table that has the same name as the entity type (returned by the Type method). All fields must be included (FieldList returns a comma-separated list). Using a table alias is mandatory in this case. The table alias is returned by the TableAbbrev method.

Example:

tablename := ec.Type(&Ent{})
alias := ec.TableAbbrev(tablename)
from := tablename + " " + alias
entities, err := ec.LoadFromQuery(nil, tablename, `SELECT `+ec.FieldList(tablename)+` FROM `+from+` WHERE ...`, args...)

func (*EntityController) SchemaSQL

func (ec *EntityController) SchemaSQL(e Entity) string

SchemaSQL creates a schema for the parameter entity.

func (*EntityController) TableAbbrev

func (ec *EntityController) TableAbbrev(name string) string

TableAbbrev returns the table name abbreviation.

func (*EntityController) Type

func (ec *EntityController) Type(e Entity) string

Type returns the name of the entity parameter.

func (*EntityController) Update

func (ec *EntityController) Update(db DB, e Entity) error

Update updates an entity in the database.

func (*EntityController) Validate

func (ec *EntityController) Validate(e Entity) error

Validate validates an entity.

type EntityDelegate

type EntityDelegate interface {
	Validate(e Entity) error
	AlterSQL(string) string
}

EntityDelegate helps out EntityController to deal with an entity type.

type EntityDeleter

type EntityDeleter interface {
	Delete(DB) error
}

EntityDeleter is implemented by an entity that uses a different method to delete itself from the database.

type EntityInserter

type EntityInserter interface {
	Insert(DB) error
}

EntityInserter is implemented by an entity that uses a different method to insert itself into the database.

type EntityReadEvent

type EntityReadEvent interface {
	Before(entityType string, query string, args []interface{}) (string, []interface{})
	After(entityType string, entities []Entity, err error) ([]Entity, error)
}

EntityReadEvent is a read event handler for an *EntityController.

type EntityResourceConfig

type EntityResourceConfig struct {
	PageLen       int
	Validator     func(data Resource, r *http.Request)
	DisableList   bool
	DisablePost   bool
	DisableGet    bool
	DisablePut    bool
	DisableDelete bool

	ListMiddlewares   []func(http.Handler) http.Handler
	PostMiddlewares   []func(http.Handler) http.Handler
	GetMiddlewares    []func(http.Handler) http.Handler
	PutMiddlewares    []func(http.Handler) http.Handler
	DeleteMiddlewares []func(http.Handler) http.Handler

	EntityResourceLister
	EntityResourceLoader
	EntityResourceExtraSchema
}

EntityResourceConfig is the configuration struct for the EntityResource.

type EntityResourceExtraSchema

type EntityResourceExtraSchema interface {
	SchemaSQL() string
	SchemaInstalled(DB) bool
}

EntityResourceExtraSchema generates extra schema that is appended to the entity's schema.

type EntityResourceLister

type EntityResourceLister interface {
	List(r *http.Request, start, limit int) (string, []interface{})
}

EntityResourceLister overrides the default listing of the entity controller.

type EntityResourceLoader

type EntityResourceLoader interface {
	Load(id string, r *http.Request) (Resource, error)
}

EntityResourceLoader overrides the default loader of the entity controller.

type EntityUpdater

type EntityUpdater interface {
	Update(DB) error
}

EntityUpdater is implemented by an entity that uses a different method to update itself in the database.

type EntityWriteEvent

type EntityWriteEvent interface {
	Before(entityType string, e Entity)
	After(entityType string, e Entity, err error) error
}

EntityWriteEvent is a write event handler for an *EntityController.

type ErrorPageData

type ErrorPageData struct {
	BackgroundColor string
	ForegroundColor string
	Code            int
	Message         string
	Logs            string
	RequestID       string
}

ErrorPageData contains data for the ErrorPage template.

type HALCurie

type HALCurie struct {
	Name      string `json:"name"`
	Href      string `json:"href"`
	Templated bool   `json:"templated"`
}

HALCurie contains documentation information for the endpoint.

type HSTSConfig

type HSTSConfig struct {
	MaxAge            time.Duration
	IncludeSubDomains bool
	HostBlacklist     []string
}

HSTSConfig contains configuration for HSTSMiddleware.

func (HSTSConfig) String

func (c HSTSConfig) String() string

type Panic

type Panic struct {
	Code       int
	Err        error
	StackTrace string
	// contains filtered or unexported fields
}

Panic is a custom panic data structure for the ErrorHandler.

func (Panic) Error

func (p Panic) Error() string

func (Panic) ServeHTTP

func (p Panic) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP outputs the error to the HTTP response.

It can render the error in 3 formats: HTML, JSON and text, depending on the Accept header. The default is HTML.

func (Panic) String

func (p Panic) String() string

func (Panic) VerboseError

func (p Panic) VerboseError() string

type Renderer

type Renderer struct {
	Code int // HTTP status code.
	// contains filtered or unexported fields
}

Renderer is a per-request struct for the Render API.

The Render API handles content negotiation with the client. The server's preference is the order how the offers are added by either the AddOffer() low-level method or the JSON()/HTML()/Text() higher level methods.

A quick example how to use the Render API:

func pageHandler(w http.ResponseWriter, r *http.Request) {
    ...
    ab.Render(r).
        HTML(pageTemplate, data).
        JSON(data)
}

In this example, the server prefers rendering an HTML page / fragment, but it can render a JSON if that's the client's preference. The default is HTML, because that is the first offer.

func NewRenderer

func NewRenderer() *Renderer

NewRenderer creates a new Renderer.

func Render

func Render(r *http.Request) *Renderer

Render gets the Renderer struct from the request context.

func (*Renderer) AddOffer

func (r *Renderer) AddOffer(mediaType string, handler func(w http.ResponseWriter)) *Renderer

AddOffer adds an offer for the content negotiation.

See the Render() method for more information. The mediaType is the content type, the handler renders the data to the ResponseWriter. You probably want to use the JSON(), HTML(), Text() methods instead of this.

func (*Renderer) Binary

func (r *Renderer) Binary(mediaType, filename string, reader io.Reader) *Renderer

Binary adds a binary file offer for the Renderer struct.

If reader is an io.ReadCloser, it will be closed automatically.

func (*Renderer) CSV

func (r *Renderer) CSV(records [][]string) *Renderer

CSV adds a CSV offer for the Renderer object.

Use this function for smaller CSV responses.

func (*Renderer) CSVChannel

func (r *Renderer) CSVChannel(records <-chan []string) *Renderer

CSVChannel adds a CSV offer for the Renderer object.

The records are streamed through a channel.

func (*Renderer) CSVGenerator

func (r *Renderer) CSVGenerator(recgen func(http.Flusher) ([]string, error)) *Renderer

CSVGenerator adds a CSV offer for the Renderer object.

The records are generated with a generator function. If the function returns an error, the streaming to the output stops.

func (*Renderer) HALJSON

func (r *Renderer) HALJSON(v interface{}) *Renderer

HALJSON adds a HAL+JSON offer to the Renderer struct.

func (*Renderer) HTML

func (r *Renderer) HTML(t *template.Template, v interface{}) *Renderer

HTML adds an HTML offer for the Renderer struct.

func (*Renderer) JSON

func (r *Renderer) JSON(v interface{}) *Renderer

JSON adds a JSON offer to the Renderer struct.

func (*Renderer) Render

func (rr *Renderer) Render(w http.ResponseWriter, r *http.Request)

Render renders the best offer to the ResponseWriter according to the client's content type preferences.

func (*Renderer) SetCode

func (r *Renderer) SetCode(code int) *Renderer

SetCode sets the HTTP status code.

func (*Renderer) Text

func (r *Renderer) Text(t string) *Renderer

Text adds a plain text offer for the Renderer struct.

func (*Renderer) XML

func (r *Renderer) XML(v interface{}, pretty bool) *Renderer

XML adds XML offer for the Renderer object.

If pretty is set, the XML will be indented. Also text/xml content type header will be sent instead of application/xml.

type Resource

type Resource interface {
}

Resource labels data for CRUD operation through API endpoints.

type ResourceController

type ResourceController struct {
	ResourceFormatter

	ExtraEndpoints func(s *Server) error
	// contains filtered or unexported fields
}

ResourceController represents a CRUD service.

func EntityResource

func EntityResource(ec *EntityController, entity Entity, config EntityResourceConfig) *ResourceController

EntityResource creates a ResourceController that exposes the entity's CRUD functions through API endpoints.

func NewResourceController

func NewResourceController(delegate ResourceControllerDelegate) *ResourceController

NewResourceController creates a ResourceController with a given delegate and sensible defaults.

func (*ResourceController) AddDeleteEvent

func (res *ResourceController) AddDeleteEvent(evt ...ResourceEvent) *ResourceController

AddDeleteEvent adds event handlers for the delete event.

func (*ResourceController) AddGetEvent

func (res *ResourceController) AddGetEvent(evt ...ResourceEvent) *ResourceController

AddGetEvent adds event handlers for the get event.

func (*ResourceController) AddListEvent

func (res *ResourceController) AddListEvent(evt ...ResourceListEvent) *ResourceController

AddListEvent adds event handlers for the list event.

func (*ResourceController) AddPostEvent

func (res *ResourceController) AddPostEvent(evt ...ResourceEvent) *ResourceController

AddPostEvent adds event handlers for the post event.

func (*ResourceController) AddPutEvent

func (res *ResourceController) AddPutEvent(evt ...ResourceEvent) *ResourceController

AddPutEvent adds event handlers for the put event.

func (*ResourceController) Delete

Delete enables the DELETE endpoint.

func (*ResourceController) Get

Get enables the GET endpoint.

func (*ResourceController) GetName

func (res *ResourceController) GetName() string

GetName returns the name of this ResourceController.

func (*ResourceController) List

List enables the listing endpoint.

func (*ResourceController) Post

Post enables the POST endpoint.

func (*ResourceController) Put

Put enables the PUT endpoint.

func (*ResourceController) Register

func (res *ResourceController) Register(srv *Server) error

func (*ResourceController) SchemaInstalled

func (res *ResourceController) SchemaInstalled(db DB) bool

func (*ResourceController) SchemaSQL

func (res *ResourceController) SchemaSQL() string

type ResourceControllerDelegate

type ResourceControllerDelegate interface {
	GetName() string
	GetTables() []string
	GetSchemaSQL() string
	SchemaInstalled(db DB) bool
}

ResourceControllerDelegate customizes a ResourceController.

type ResourceDeleteDelegate

type ResourceDeleteDelegate interface {
	Load(id string, r *http.Request) (Resource, error)
	Delete(data Resource, r *http.Request) error
}

ResourceDeleteDelegate helps a ResourceController to handle DELETE for a resource.

type ResourceEvent

type ResourceEvent interface {
	Before(*http.Request, Resource)
	Inside(*http.Request, Resource)
	After(*http.Request, Resource)
}

ResourceEvent is used as an event handler for ResourceController endpoints.

type ResourceEventCallback

type ResourceEventCallback struct {
	BeforeCallback func(*http.Request, Resource)
	InsideCallback func(*http.Request, Resource)
	AfterCallback  func(*http.Request, Resource)
}

ResourceEventCallback is a simple implementation of ResourceEvent that invokes callbacks.

func (ResourceEventCallback) After

func (c ResourceEventCallback) After(r *http.Request, res Resource)

func (ResourceEventCallback) Before

func (c ResourceEventCallback) Before(r *http.Request, res Resource)

func (ResourceEventCallback) Inside

func (c ResourceEventCallback) Inside(r *http.Request, res Resource)

type ResourceFormatter

type ResourceFormatter interface {
	FormatSingle(Resource, *Renderer)
	FormatMulti(ResourceList, *Renderer)
}

ResourceFormatter formats resources for the HTTP response.

type ResourceGetDelegate

type ResourceGetDelegate interface {
	Load(id string, r *http.Request) (Resource, error)
}

ResourceGetDelegate helps a ResourceController to handle GET for a resource.

type ResourceList

type ResourceList struct {
	Items []Resource `json:"items"`

	Curies []HALCurie               `json:"-"`
	Rels   map[string][]interface{} `json:"-"`
	// contains filtered or unexported fields
}

ResourceList is an extended list of resources.

func (ResourceList) MarshalJSON

func (rl ResourceList) MarshalJSON() ([]byte, error)

type ResourceListDelegate

type ResourceListDelegate interface {
	List(r *http.Request, start, limit int) ([]Resource, error)
	PageLength() int
}

ResourceListDelegate helps a ResourceController to list resources.

type ResourceListEvent

type ResourceListEvent interface {
	Before(*http.Request)
	After(*http.Request, *ResourceList)
}

ResourceListEvent is used as an event handler for a listing endpoint.

type ResourceListEventCallback

type ResourceListEventCallback struct {
	BeforeCallback func(*http.Request)
	AfterCallback  func(*http.Request, *ResourceList)
}

ResourceListEventCallback is a simple implementation of ResourceListEvent that invokes callbacks.

func (ResourceListEventCallback) After

func (ResourceListEventCallback) Before

func (c ResourceListEventCallback) Before(r *http.Request)

type ResourcePathOverrider

type ResourcePathOverrider interface {
	OverridePath(string) string
}

ResourcePathOverrider can be implemented by a ResourceDelegate to change the path pattern for the given resource operation.

type ResourcePostDelegate

type ResourcePostDelegate interface {
	Empty() Resource
	Validate(data Resource, r *http.Request)
	Insert(data Resource, r *http.Request) error
}

ResourcePostDelegate helps a ResourceController to handle POST for a resource.

type ResourcePutDelegate

type ResourcePutDelegate interface {
	Empty() Resource
	Load(id string, r *http.Request) (Resource, error)
	GetID(Resource) string
	Validate(data Resource, r *http.Request)
	Update(data Resource, r *http.Request) error
}

ResourcePutDelegate helps a ResourceController to handle PUT for a resource.

type SecretKey

type SecretKey []byte

SecretKey will be used to sign and verify the cookies.

type Server

type Server struct {
	*httprouter.Router

	Logger    *log.Log
	TLSConfig *tls.Config
	// contains filtered or unexported fields
}

Server is the main server struct.

func NewServer

func NewServer(conn *sql.DB) *Server

NewServer creates a new server with a database connection.

func PetBunny

func PetBunny(cfg *viper.Viper, logger *log.Log, topMiddlewares ...func(http.Handler) http.Handler) (*Server, error)

PetBunny sets up a Server with recommended middlewares.

The parameters logger and eh can be nil, defaults will be log.DefaultOSLogger() and HandleErrors().

topMiddlewares are middlewares that gets applied right after the logger middlewares, but before anything else.

Viper has to be set up, and it has to contain a few values:

- CookieSecret string: hex representation of the key bytes. Must be set.

- db string: connection string to Postgres. Must be set.

- DBMaxIdleConn int: max idle connections. Defaults to 0 (no open connections are retained).

- DBMaxOpenConn int: max open connections. Defaults to 0 (unlimited).

- LogLevel int: log level for the logger. Use the numeric values of the log.LOG_* constants.

- hsts (hsts.maxage float, hsts.includesubdomains bool, hsts.hostblacklist []string): configuration values for the HSTS middleware. See HSTSConfig structure

- gzip bool: enabled the gzip middleware. Default is true.

- CookiePrefix string: prefix for the session and the csrf cookies.

- CookieURL string: domain and path configuration for the cookies.

- assetsDir string: assets directory. The value - skips setting it up.

- publicDir string: public directory. The value - skips setting it up.

- root bool: sets / to serve assetsDir/index.html. Default is true.

- hostwhitelist: a string array of hosts that are whitelisted for letsencrypt. If set, https will be enabled with letsencrypt.

func (*Server) AddFile

func (s *Server) AddFile(path, file string) *Server

Adds a local file to the router.

func (*Server) AddLocalDir

func (s *Server) AddLocalDir(prefix, path string) *Server

AddLocalDir adds a local directory to the router.

func (*Server) Delete

func (s *Server) Delete(path string, handler http.Handler, middlewares ...func(http.Handler) http.Handler)

Delete adds a DELETE handler to the router.

func (*Server) DeleteF

func (s *Server) DeleteF(path string, handler http.HandlerFunc, middlewares ...func(http.Handler) http.Handler)

DeleteF adds a DELETE HandlerFunc to the router.

func (*Server) EnableAutocert

func (s *Server) EnableAutocert(caDirEndpoint, cacheDir string, hostWhitelist ...string)

EnableAutocert adds autocert to the server.

caDirEndpoint points to a ca directory endpoint. cacheDir defaults to "private/autocert-cache" when empty. If you use the recommended app layout, leave it empty. hostWhitelist is a list of hosts where the SSL certificate is valid. Supply at least one domain, else it won't work.

func (*Server) EnableLetsEncrypt

func (s *Server) EnableLetsEncrypt(cacheDir string, hostWhitelist ...string)

EnableLetsEncrypt adds autocert to the server with LetsEncrypt CA dir.

See the documentation of EnableAutocert for cacheDir and hostWhitelist

func (*Server) Get

func (s *Server) Get(path string, handler http.Handler, middlewares ...func(http.Handler) http.Handler)

Get adds a GET handler to the router.

func (*Server) GetDBConnection

func (s *Server) GetDBConnection() DB

GetDBConnection returns the server's DB connection if there's any.

func (*Server) GetF

func (s *Server) GetF(path string, handler http.HandlerFunc, middlewares ...func(http.Handler) http.Handler)

GetF adds a GET HandlerFunc to the router.

func (*Server) Handle

func (s *Server) Handle(method, path string, handler http.Handler, middlewares ...func(http.Handler) http.Handler)

Handle adds a handler to the router.

The middleware list will be applied to this handler only.

func (*Server) Handler

func (s *Server) Handler() http.Handler

Handler creates a http.Handler from the server (using the middlewares and the router).

func (*Server) Head

func (s *Server) Head(path string, handler http.Handler, middlewares ...func(http.Handler) http.Handler)

Head adds a HEAD handler to the router.

func (*Server) HeadF

func (s *Server) HeadF(path string, handler http.HandlerFunc, middlewares ...func(http.Handler) http.Handler)

HeadF adds a HEAD HandlerFunc to the router.

func (*Server) Options

func (s *Server) Options(path string, handler http.Handler, middlewares ...func(http.Handler) http.Handler)

Options adds an OPTIONS handler to the router.

func (*Server) OptionsF

func (s *Server) OptionsF(path string, handler http.HandlerFunc, middlewares ...func(http.Handler) http.Handler)

OptionsF adds an OPTIONS HandlerFunc to the router.

func (*Server) Patch

func (s *Server) Patch(path string, handler http.Handler, middlewares ...func(http.Handler) http.Handler)

Patch adds a PATCH handler to the router.

func (*Server) PatchF

func (s *Server) PatchF(path string, handler http.HandlerFunc, middlewares ...func(http.Handler) http.Handler)

PatchF adds a PATCH HandlerFunc to the router.

func (*Server) Post

func (s *Server) Post(path string, handler http.Handler, middlewares ...func(http.Handler) http.Handler)

Post adds a POST handler to the router.

func (*Server) PostF

func (s *Server) PostF(path string, handler http.HandlerFunc, middlewares ...func(http.Handler) http.Handler)

PostF adds a POST HandlerFunc to the router.

func (*Server) Put

func (s *Server) Put(path string, handler http.Handler, middlewares ...func(http.Handler) http.Handler)

Put adds a PUT handler to the router.

func (*Server) PutF

func (s *Server) PutF(path string, handler http.HandlerFunc, middlewares ...func(http.Handler) http.Handler)

PutF adds a PUT HandlerFunc to the router.

func (*Server) RegisterService

func (s *Server) RegisterService(svc Service)

RegisterService adds a service on the server.

See the Service interface for more information.

func (*Server) StartHTTP

func (s *Server) StartHTTP(addr string) error

StartHTTP starts the server.

func (*Server) StartHTTPS

func (s *Server) StartHTTPS(addr, certFile, keyFile string) error

StartHTTPS starts the server.

func (*Server) Use

func (s *Server) Use(middleware ...func(http.Handler) http.Handler)

Use adds middlewares to the end of the middleware chain.

func (*Server) UseHandler

func (s *Server) UseHandler(h http.Handler)

UseHandler uses a http.Handler as a middleware.

func (*Server) UseTop

func (s *Server) UseTop(middlewares ...func(http.Handler) http.Handler)

UseTop adds middlewares to the beginning of the middleware chain.

type Service

type Service interface {
	// Register the Service endpoints
	Register(*Server) error
	// Checks if the schema is installed
	SchemaInstalled(db DB) bool
	// Construct SQL string to install the schema
	SchemaSQL() string
}

Service is a collection of endpoints that logically belong together or operate on the same part of the database schema.

type Session

type Session map[string]string

Session represents a session which will be stored in the session cookies.

func GetSession

func GetSession(r *http.Request) Session

GetSession returns the session from the http request context.

func (Session) Id

func (s Session) Id() string

Id returns the session ID. If there isn't one, it generates it.

type TestClient

type TestClient struct {
	Client *http.Client
	Token  string
	// contains filtered or unexported fields
}

TestClient is a wrapper on the top of http.Client for integration tests.

func NewTestClient

func NewTestClient(base string) *TestClient

NewTestClient initializes TestClient.

The wrapped http.Client will get an empty cookie jar.

func NewTestClientWithToken

func NewTestClientWithToken(base string) *TestClient

NewTestClientWithToken initializes a TestClient and retrieves a CSRF token.

func (*TestClient) AssertFile

func (tc *TestClient) AssertFile(resp *http.Response, path string)

AssertFile asserts that the response body is equal to a file.

func (*TestClient) AssertJSON

func (tc *TestClient) AssertJSON(resp *http.Response, v, d interface{})

AssetJSON decodes the JSON body of the response into v, and matches it with d.

func (*TestClient) ConsumePrefix

func (tc *TestClient) ConsumePrefix(r *http.Response) bool

ConsumePrefix consumes the JSONPrefix from the response body.

func (*TestClient) GetToken

func (tc *TestClient) GetToken()

GetToken retrieves the token from the TestServer for TestClient.

func (*TestClient) JSONBuffer

func (tc *TestClient) JSONBuffer(v interface{}) io.Reader

JSONBuffer creates an in-memory buffer of a serialized JSON value.

func (*TestClient) ReadBody

func (tc *TestClient) ReadBody(r *http.Response, JSONPrefix bool) string

ReadBody reads the response body into a string.

func (*TestClient) Request

func (tc *TestClient) Request(method, endpoint string, body io.Reader, processReq func(*http.Request), processResp func(*http.Response), statusCode int)

Request sends a request to a TestServer.

The method and endpoint parameters are mandatory. The body can be nil if the request does not have a body. The prcessReq function can modify the request, but it can be nil. The processResp function can deal with the response, but it can be nil as well. The statusCode parameter is the expected status code.

type TestServer

type TestServer struct {
	ConfigName string
	AssetsDir  string
	Addr       string
}

TestServer is a temporary Server for integration tests.

func (*TestServer) Start

func (s *TestServer) Start(setup func(cfg *viper.Viper, s *Server) error) *viper.Viper

Start starts a Server with test-optimized settings.

func (*TestServer) StartAndCleanUp

func (s *TestServer) StartAndCleanUp(m *testing.M, setup func(cfg *viper.Viper, s *Server) error)

StartAndCleanUp takes control of the TestMain function.

It starts a Server and when the tests are finished it clears the database.

type Validator

type Validator interface {
	Validate() error
}

Validator interface is implemented by types that require validation during some point in their lifecycle.

type VerboseError

type VerboseError interface {
	// Error that is displayed in the logs and debug messages. Should contain diagnostical information.
	Error() string
	// Error that is displayed to the end user.
	VerboseError() string
}

VerboseError extends the built-in error interface with a message that is displayed to the end user.

func NewVerboseError

func NewVerboseError(err, verboseMessage string) VerboseError

Creates a new verbose error message.

If err is an empty string, then verboseMessage will be used it instead.

func WrapError

func WrapError(err error, verboseMessage string) VerboseError

WrapError wraps an error message into a VerboseError.

Directories

Path Synopsis
cmd
abt
lib
log
Generic logger package There are 3 loglevels for every Log.
Generic logger package There are 3 loglevels for every Log.
providers
services
auth
Authentication service.
Authentication service.
tools

Jump to

Keyboard shortcuts

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