Documentation
¶
Index ¶
- Variables
- func AdminHandle(handle func(ctx, *User) error) func(ctx) error
- func AuthHandle(handle func(ctx, *User) error) func(ctx) error
- func GenerateAuthToken(user *User, renew bool) (string, error)
- func GenerateVerifier(key string) string
- func GetMD5Hash(text string) string
- func Init()
- func InitWrit(w *Writ) error
- func Int64ToString(n int64) string
- func IsUsernameAvailable(username string) bool
- func MD5Hash(data []byte) string
- func MakeEmail() *mailyak.MailYak
- func Ping(endpoint string) bool
- func Query(query string, vars obj) ([]obj, error)
- func QueryOne(query string, vars obj, result interface{}) error
- func RandBytes(size int) []byte
- func RandStr(size int) string
- func RoleHandle(roles []Role, handle func(ctx, *User) error) func(ctx) error
- func SendEmail(m *mailyak.MailYak) error
- func SendErr(c ctx, code int, err string) error
- func SendErrJSON(c ctx, code int, err string) error
- func SendJSON(c ctx, code int, msg interface{}) error
- func SendMsgpack(c ctx, code int, msg interface{}) error
- func UnmarshalJSONFile(location string, marshaled interface{}) error
- type AuthRequest
- type Branca
- type BrancaToken
- type CodedResponse
- type Config
- type Encoding
- type LogEntry
- type PageError
- type Role
- type Template
- type Timeframe
- type User
- func AuthenticateUser(email, username string) (User, error)
- func CredentialCheck(c ctx) (*User, error)
- func UserByDetails(email, username string) (User, error)
- func UserByEmail(email string) (User, error)
- func UserByKey(key string) (User, error)
- func UserByUsername(username string) (User, error)
- func ValidateAuthToken(token string) (User, bool)
- func VerifyUser(verifier string) (*User, error)
- type Writ
- type WritQuery
Constants ¶
This section is empty.
Variables ¶
var ( // VerifiedSubject auth email subject VerifiedSubject string // UnverifiedSubject auth email subject for first timers UnverifiedSubject string )
var ( CreateUser = `` /* 191-byte string literal not displayed */ FindUSERByUsername = `FOR u IN users FILTER u.username == @username RETURN u` FindUSERByEmail = `FOR u IN users FILTER u.email == @email RETURN u` FindUserByDetails = `FOR u IN users FILTER u.email == @email && u.username == @username RETURN u` )
Common DB Queries
var ( // ErrInvalidToken ... ErrInvalidToken = errors.New("invalid base62 token") // ErrInvalidTokenVersion ... ErrInvalidTokenVersion = errors.New("invalid token version") // ErrBadKeyLength ... ErrBadKeyLength = errors.New("bad key length") // ErrExpiredToken ... ErrExpiredToken = errors.New("token has expired") )
var ( // DB central arangodb database for querying DB driver.Database // Users arangodb collection containing user data Users driver.Collection // Writs arangodb writ collection containing writs Writs driver.Collection // Logs arangodb log collection for storing the app's logs Logs driver.Collection // RateLimits arangodb ratelimits collection RateLimits driver.Collection // DBHealthTicker to see if the DB is still ok DBHealthTicker *time.Ticker // DBAlive does the db still live? DBAlive bool )
var ( SMTPAuth smtp.Auth DKIMSignature dkim.Signature EmailConf = struct { Address string Server string Port string FromName string Email string Password string }{} PrivateDKIMkey *rsa.PrivateKey )
EmailSettings - email configuration and setup to send authtokens and stuff
var ( // ErrIncompleteUser user is half baked, best get them in the DB before doing funny stuff ErrIncompleteUser = errors.New("cannot mutate a user that is incomplete or not in database") // ErrBadDBConnection bad database connection, try different details ErrBadDBConnection = StaticErrorResponse(500, "bad database connection error, try different details") // ErrIncompleteWrit someone probably tried to mutate a writ that is invalid or non existing (in db) ErrIncompleteWrit = StaticErrorResponse(500, `attempted to modify either an invalid writ, or one not in the db`) // ErrMissingTags writ is missing tags ErrMissingTags = errors.New(`writ doesn't have any tags, add some`) // ErrAuthorIsNoUser writ's author is persona non grata ErrAuthorIsNoUser = errors.New(`writ author is not a registered user`) UnauthorizedError = StaticErrorResponse(403, "unauthorized request, cannot proceed") // InvalidDetailsError invalid details, could not authorize user InvalidDetailsError = StaticErrorResponse(401, "invalid details, could not authorize user") // BadUsernameError invalid username, could not authorize user BadUsernameError = StaticErrorResponse(401, "invalid username, could not authorize user") // BadEmailError invalid email, could not authorize user BadEmailError = StaticErrorResponse(401, "invalid email, could not authorize user") // BadRequestError bad request, check details and try again BadRequestError = StaticErrorResponse(400, "bad request, check details and try again") // ServerDecodeError ran into trouble decoding your request ServerDecodeError = StaticErrorResponse(400, "ran into trouble decoding your request") // ServerDBError server error, could not complete your request ServerDBError = StaticErrorResponse(500, "server error, could not complete your request") // AlreadyLoggedIn user is logged in, but they tried to login again. AlreadyLoggedIn = StaticErrorResponse(203, "You're already logged in :D") // RateLimitingError somebody probably sent too many emails RateLimitingError = StaticErrorResponse(429, "ratelimiting: too many auth requests/emails, wait a bit and try again") // NoSuchWrit could not find a writ matching the query/request NoSuchWrit = StaticErrorResponse(404, "couldn't find a writ like that") // RequestQueryOverLimitMembers a member is requesting too many things at once RequestQueryOverLimitMembers = StaticErrorResponse(403, "requesting too many items at once, members >= 200") // RequestQueryOverLimit a viewer (non-member-user) is requesting too many things at once RequestQueryOverLimit = StaticErrorResponse(403, "requesting too many items at once, non-members >= 100") // SuccessMsg send a success response SuccessMsg = StaticResponse(203, "success!") // DeleteWritError there was trouble when attempting to delete a writ, prolly database/bad-input related DeleteWritError = StaticErrorResponse(500, "could not delete writ, maybe it didn't exist in the first place") )
Errors for days
var ( // AppName name of this application AppName string // AppDomain web domain of this application AppDomain string // DKIMKey private dkim key used for email signing DKIMKey []byte // DevMode run the app in production or dev-mode DevMode = false // Tokenator token generator/decoder Tokenator *Branca // Verinator token generator/decoder for verification codes only Verinator *Branca // MaintainerEmails the list of people to email if all hell breaks loose MaintainerEmails []string // AssetsDir path to all the servable static assets AssetsDir string // AppLocation where this application lives, it's used for self management AppLocation string // LocalIP is the IP of the machine/env the app is running on LocalIP string // StartupDate when the app started running StartupDate time.Time // LogQ server logging LogQ = []LogEntry{} // Server is the echo instance Server *echo.Echo // Conf contains various information about/for the setup Conf *Config // Cache serves memory cached (gzipped) static content Cache *tr.AssetCache )
var (
// RandomDictionary the character range of the randomBytes and randomString functions
RandomDictionary = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
)
Functions ¶
func AdminHandle ¶
AdminHandle create a GET route, accessible only to admin users
func AuthHandle ¶
AuthHandle create a GET route, accessible only to authenticated users
func GenerateAuthToken ¶
GenerateAuthToken create a branca token
func GenerateVerifier ¶
GenerateVerifier create a branca token
func GetMD5Hash ¶
GetMD5Hash turn []byte into a MD5 hashed string
func Int64ToString ¶
Int64ToString convert int64 to strings (for ports and stuff when you want to make json less stringy)
func IsUsernameAvailable ¶
IsUsernameAvailable checks that the username is as of yet unused
func RoleHandle ¶
RoleHandle create a GET route, accessible only to users with certain Roles
func SendErrJSON ¶
SendErrJSON send a json encoded error message like {"err": "msg"}
func SendMsgpack ¶
SendMsgpack send a msgpack encoded response with a status code
func UnmarshalJSONFile ¶
UnmarshalJSONFile read json files and go straight to unmarshalling
Types ¶
type AuthRequest ¶
type AuthRequest struct { Email string `json:"email" msgpack:"email"` Username string `json:"username" msgpack:"username"` }
AuthRequest for unmarshalling the post body
type Branca ¶
type Branca struct { Key string // contains filtered or unexported fields }
Branca holds a key of exactly 32 bytes. The nonce and timestamp are used for acceptance tests.
func (*Branca) Decode ¶
func (b *Branca) Decode(data string) (BrancaToken, error)
Decode decode token and return payload string, expiration time.Time, and an error if any
func (*Branca) Encode ¶
Encode encodes the data matching the format: Version (byte) || Timestamp ([4]byte) || Nonce ([24]byte) || Ciphertext ([]byte) || Tag ([16]byte)
func (*Branca) EncodeWithTime ¶
EncodeWithTime encodes the data matching the format: Version (byte) || Timestamp ([4]byte) || Nonce ([24]byte) || Ciphertext ([]byte) || Tag ([16]byte)
type BrancaToken ¶
BrancaToken contains all the decomposed parts of a branca token
func (*BrancaToken) ExpiresBefore ¶
func (tk *BrancaToken) ExpiresBefore(t time.Time) bool
ExpiresBefore checks whether the token would expire before a certain time
type CodedResponse ¶
CodedResponse standardized way to send a prebuilt response with a status code
func MakeCodedResponse ¶
func MakeCodedResponse(code int, msg string, primitive interface{}) *CodedResponse
MakeCodedResponse easilly generate an CodedResponse
func StaticErrorResponse ¶
func StaticErrorResponse(code int, msg string) *CodedResponse
StaticErrorResponse generates a new error qua CodedResponse
func StaticResponse ¶
func StaticResponse(code int, msg string) *CodedResponse
StaticResponse generates a new simple CodedResponse {msg: '...'}
func (*CodedResponse) Error ¶
func (e *CodedResponse) Error() string
func (*CodedResponse) Send ¶
func (e *CodedResponse) Send(c ctx) error
Send send off the error through an echo context as msgpack data with a status code
func (*CodedResponse) SendJSON ¶
func (e *CodedResponse) SendJSON(c ctx) error
SendJSON send off the error through an echo context as json data with a status code
type Config ¶
type Config struct { AppName string `json:"appname,omitempty" toml:"appname,omitempty"` Domain string `json:"domain,omitempty" toml:"domain,omitempty"` MaintainerEmail string `json:"maintainer_email,omitempty" toml:"maintainer_email,omitempty"` DevMode bool `json:"devmode,omitempty" toml:"devmode,omitempty"` Address string `json:"address" toml:"address"` SecondaryServerAddress string `json:"secondary_server_address" toml:"secondary_server_address"` DevAddress string `json:"dev_address,omitempty" toml:"dev_address,omitempty"` DevSecondaryServerAddress string `json:"dev_secondary_server_address,omitempty" toml:"dev_secondary_server_address,omitempty"` PreferMsgpack bool `json:"prefer_msgpack,omitempty" toml:"prefer_msgpack,omitempty"` AutoPush bool `json:"autopush,omitempty" toml:"autopush,omitempty"` AutoCert bool `json:"autocert,omitempty" toml:"autocert,omitempty"` DevAutoCert bool `json:"dev_autocert,omitempty" toml:"dev_autocert,omitempty"` Whitelist []string `json:"whitelist,omitempty" toml:"whitelist,omitempty"` Certs string `json:"certs,omitempty" toml:"certs,omitempty"` TLSKey string `json:"tls_key,omitempty" toml:"tls_key,omitempty"` TLSCert string `json:"tls_cert,omitempty" toml:"tls_cert,omitempty"` Templates string `json:"templates,omitempty" toml:"templates,omitempty"` Assets string `json:"assets,omitempty" toml:"assets,omitempty"` DoNotWatchAssets bool `json:"do_not_watch_assets,omitempty" toml:"do_not_watch_assets,omitempty"` Private string `json:"private,omitempty" toml:"private,omitempty"` Cache string `json:"cache,omitempty" toml:"cache,omitempty"` Raw map[string]interface{} `json:"-" toml:"-"` }
Config holds all the information necessary to fire up a mak instance
type Encoding ¶
type Encoding struct {
// contains filtered or unexported fields
}
Encoding is a custom base encoding defined by an alphabet. It should bre created using NewEncoding function
func NewBaseEncoding ¶
NewBaseEncoding returns a custom base encoder defined by the alphabet string. The alphabet should contain non-repeating characters. Ordering is important. Example alphabets:
- base2: 01
- base16: 0123456789abcdef
- base32: 0123456789ABCDEFGHJKMNPQRSTVWXYZ
- base62: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
type LogEntry ¶
type LogEntry struct { Method string `json:"method,omitempty"` Path string `json:"path,omitempty"` IP string `json:"client,omitempty"` Code int `json:"code,omitempty"` Latency float64 `json:"latency,omitempty"` Start time.Time `json:"start,omitempty"` End time.Time `json:"end,omitempty"` BytesOut int64 `json:"bytesOut,omitempty"` BytesIn int64 `json:"bytesIn,omitempty"` DevMode bool `json:"devmode,omitempty"` Err string `json:"err,omitempty"` Headers obj `json:"headers,omitempty"` }
LogEntry is a struct containing request logging info
type PageError ¶
PageError implements error but can send an .html file as a response
var Err404NotFound *PageError
Err404NotFound is the standard 404 error response returned by Anend
func MakePageErr ¶
MakePageErr generates a new *PageError
type Template ¶
type Template struct { NoWatch bool Templates string Watcher *fsnotify.Watcher sync.Mutex // contains filtered or unexported fields }
Template to implement echo.Renderer
var Renderer *Template
Renderer is the central app renderer
func (*Template) Exec ¶
Exec is a surfaced method to call ExecuteTemplates on the underlying template(s)
type Timeframe ¶
type Timeframe struct { Start time.Time `json:"start,omitempty" msgpack:"start"` End time.Time `json:"end,omitempty" msgpack:"end"` }
Timeframe a distance of time between a .Start time and a .Finish time
type User ¶
type User struct { Key string `json:"_key,omitempty"` Email string `json:"email"` EmailMD5 string `json:"emailmd5"` Username string `json:"username"` Description string `json:"description,omitempty"` Verifier string `json:"verifier,omitempty"` Created time.Time `json:"created,omitempty"` Logins []time.Time `json:"logins,omitempty"` Sessions []time.Time `json:"sessions,omitempty"` Roles []Role `json:"roles,omitempty"` Friends []string `json:"friends,omitempty"` Exp int64 `json:"exp,omitempty"` Subscriber bool `json:"subscriber,omitempty"` }
User struct describing a user account
func AuthenticateUser ¶
AuthenticateUser create and/or authenticate a user
func CredentialCheck ¶
CredentialCheck get an authorized user from a route handler's context
func UserByDetails ¶
UserByDetails attempt to get a user via their email/username combo
func UserByEmail ¶
UserByEmail get user with a certain email
func UserByUsername ¶
UserByUsername get user with a certain username
func ValidateAuthToken ¶
ValidateAuthToken and return a user if ok
func VerifyUser ¶
VerifyUser from a verifier token, check that a user has verified their email at least once
func (*User) SetupVerifier ¶
SetupVerifier initiate verification process with verifier and db update
type Writ ¶
type Writ struct { Key string `json:"_key,omitempty" msgpack:"_key,omitempty"` Type string `json:"type,omitempty" msgpack:"type,omitempty"` Title string `json:"title,omitempty" msgpack:"title,omitempty"` AuthorKey string `json:"authorkey,omitempty" msgpack:"authorkey,omitempty"` Author string `json:"author,omitempty" msgpack:"author,omitempty"` Content string `json:"content,omitempty" msgpack:"content,omitempty"` Injection string `json:"injection,omitempty" msgpack:"injection,omitempty"` Markdown string `json:"markdown,omitempty" msgpack:"markdown,omitempty"` Description string `json:"description,omitempty" msgpack:"description,omitempty"` Slug string `json:"slug,omitempty" msgpack:"slug,omitempty"` Tags []string `json:"tags,omitempty" msgpack:"tags,omitempty"` Edits []time.Time `json:"edits,omitempty" msgpack:"edits,omitempty"` Created time.Time `json:"created,omitempty" msgpack:"created,omitempty"` Views int64 `json:"views,omitempty" msgpack:"views,omitempty"` ViewedBy []string `json:"viewedby,omitempty" msgpack:"viewedby,omitempty"` LikedBy []string `json:"likedby,omitempty" msgpack:"likedby,omitempty"` Public bool `json:"public,omitempty" msgpack:"public,omitempty"` MembersOnly bool `json:"membersonly,omitempty" msgpack:"membersonly,omitempty"` NoComments bool `json:"nocomments,omitempty" msgpack:"nocomments,omitempty"` Roles []int64 `json:"roles,omitempty" msgpack:"roles,omitempty"` }
Writ - struct representing a post or document in the database
func (*Writ) RenderContent ¶
func (w *Writ) RenderContent()
RenderContent from .Markdown generate html and set .Content
type WritQuery ¶
type WritQuery struct { One bool `json:"one,omitempty" msgpack:"one,omitempty"` Key string `json:"_key,omitempty" msgpack:"_key,omitempty"` PrivateOnly bool `json:"privateonly,omitempty" msgpack:"privateonly,omitempty"` IncludePrivate bool `json:"includeprivate,omitempty" msgpack:"includeprivate,omitempty"` EditorMode bool `json:"editormode,omitempty" msgpack:"editormode,omitempty"` Extensive bool `json:"extensive,omitempty" msgpack:"extensive,omitempty"` UpdateViews bool `json:"updateviews,omitempty" msgpack:"updateviews,omitempty"` Comments bool `json:"comments,omitempty" msgpack:"comments,omitempty"` MembersOnly bool `json:"membersonly,omitempty" msgpack:"membersonly,omitempty"` IncludeMembersOnly bool `json:"includemembersonly,omitempty" msgpack:"includemembersonly,omitempty"` DontSort bool `json:"dontsort,omitempty" msgpack:"dontsort,omitempty"` Vars map[string]interface{} `json:"vars,omitempty" msgpack:"vars,omitempty"` ViewedBy string `json:"viewedby,omitempty" msgpack:"viewedby,omitempty"` LikedBy string `json:"likedby,omitempty" msgpack:"likedby,omitempty"` Viewer string `json:"viewer,omitempty" msgpack:"viewer,omitempty"` Title string `json:"title,omitempty" msgpack:"title,omitempty"` Slug string `json:"slug,omitempty" msgpack:"slug,omitempty"` Author string `json:"author,omitempty" msgpack:"author,omitempty"` Created time.Time `json:"created,omitempty" msgpack:"created,omitempty"` Between Timeframe `json:"between,omitempty" msgpack:"between,omitempty"` Roles []int64 `json:"roles,omitempty" msgpack:"roles,omitempty"` Limit []int64 `json:"limit,omitempty" msgpack:"limit,omitempty"` Tags []string `json:"tags,omitempty" msgpack:"tags,omitempty"` Omissions []string `json:"omissions,omitempty" msgpack:"omissions,omitempty"` }
WritQuery a easier way to query the db for writs