kamux

package
v1.2.7 Latest Latest
Warning

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

Go to latest
Published: Dec 25, 2022 License: BSD-3-Clause Imports: 43 Imported by: 0

Documentation

Index

Constants

View Source
const (
	GET int = iota
	POST
	PUT
	PATCH
	DELETE
	HEAD
	OPTIONS
	WS
	SSE
)

Variables

View Source
var (
	COOKIES_Expires  = 7 * 24 * time.Hour
	COOKIES_SameSite = http.SameSiteStrictMode
	COOKIES_HttpOnly = true
	COOKIES_Secure   = false
)
View Source
var (
	CORSDebug    = false
	ReadTimeout  = 5 * time.Second
	WriteTimeout = 20 * time.Second
	IdleTimeout  = 20 * time.Second
)
View Source
var Admin = func(handler Handler) Handler {
	const key utils.ContextKey = "user"
	return func(c *Context) {
		session, err := c.GetCookie("session")
		if err != nil || session == "" {

			c.DeleteCookie("session")
			c.Status(http.StatusTemporaryRedirect).Redirect("/admin/login")
			return
		}
		if SESSION_ENCRYPTION {
			session, err = encryptor.Decrypt(session)
			if err != nil {
				c.Status(http.StatusTemporaryRedirect).Redirect("/admin/login")
				return
			}
		}
		user, err := orm.Model[models.User]().Where("uuid = ?", session).One()

		if err != nil {

			c.Status(http.StatusTemporaryRedirect).Redirect("/admin/login")
			return
		}

		if !user.IsAdmin {
			c.Status(403).Text("Middleware : Not allowed to access this page")
			return
		}

		ctx := context.WithValue(c.Request.Context(), key, user)
		*c = Context{
			ResponseWriter: c.ResponseWriter,
			Request:        c.Request.WithContext(ctx),
			Params:         c.Params,
		}

		handler(c)
	}
}
View Source
var Auth = func(handler Handler) Handler {
	const key utils.ContextKey = "user"
	return func(c *Context) {
		session, err := c.GetCookie("session")
		if err != nil || session == "" {

			c.DeleteCookie("session")
			handler(c)
			return
		}
		if SESSION_ENCRYPTION {
			session, err = encryptor.Decrypt(session)
			if err != nil {
				handler(c)
				return
			}
		}

		user, err := orm.Model[models.User]().Where("uuid = ?", session).One()
		if err != nil {

			handler(c)
			return
		}

		ctx := context.WithValue(c.Request.Context(), key, user)
		*c = Context{
			ResponseWriter: c.ResponseWriter,
			Request:        c.Request.WithContext(ctx),
			Params:         c.Params,
		}
		handler(c)
	}
}

AuthMiddleware can be added to any handler to get user cookie authentication and pass it to handler and templates

View Source
var BasicAuth = func(next Handler, user, pass string) Handler {
	return func(c *Context) {

		username, password, ok := c.Request.BasicAuth()
		if ok {

			usernameHash := sha256.Sum256([]byte(username))
			passwordHash := sha256.Sum256([]byte(password))
			expectedUsernameHash := sha256.Sum256([]byte(user))
			expectedPasswordHash := sha256.Sum256([]byte(pass))

			usernameMatch := (subtle.ConstantTimeCompare(usernameHash[:], expectedUsernameHash[:]) == 1)
			passwordMatch := (subtle.ConstantTimeCompare(passwordHash[:], expectedPasswordHash[:]) == 1)

			if usernameMatch && passwordMatch {
				next(c)
				return
			}
		}

		c.ResponseWriter.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
		http.Error(c.ResponseWriter, "Unauthorized", http.StatusUnauthorized)
	}
}
View Source
var CSRF = csrf.CSRF
View Source
var Csrf = func(handler Handler) Handler {
	oncc.Do(func() {
		if !csrf.Used {
			i := time.Now()
			eventbus.Subscribe("csrf-clean", func(data string) {
				if data != "" {
					csrf.Csrf_tokens.Delete(data)
				}
				if time.Since(i) > time.Hour {
					csrf.Csrf_tokens.Flush()
					i = time.Now()
				}
			})
			csrf.Used = true
		}
	})
	return func(c *Context) {
		switch c.Method {
		case "GET":
			token := c.Request.Header.Get("X-CSRF-Token")
			tok, ok := csrf.Csrf_tokens.Get(token)

			if token == "" || !ok || token != tok.Value || tok.Retry > csrf.CSRF_TIMEOUT_RETRY {
				t, _ := encryptor.Encrypt(csrf.Csrf_rand)
				csrf.Csrf_tokens.Set(t, csrf.Token{
					Value:   t,
					Used:    false,
					Retry:   0,
					Remote:  c.Request.UserAgent(),
					Created: time.Now(),
				})
				http.SetCookie(c.ResponseWriter, &http.Cookie{
					Name:     "csrf_token",
					Value:    t,
					Path:     "/",
					Expires:  time.Now().Add(csrf.CSRF_CLEAN_EVERY),
					SameSite: http.SameSiteStrictMode,
				})
			} else {
				if token != tok.Value {
					http.SetCookie(c.ResponseWriter, &http.Cookie{
						Name:     "csrf_token",
						Value:    tok.Value,
						Path:     "/",
						Expires:  time.Now().Add(csrf.CSRF_CLEAN_EVERY),
						SameSite: http.SameSiteStrictMode,
					})
				}
			}
		case "POST", "PATCH", "PUT", "UPDATE", "DELETE":
			token := c.Request.Header.Get("X-CSRF-Token")
			tok, ok := csrf.Csrf_tokens.Get(token)
			if !ok || token == "" || tok.Used || tok.Retry > csrf.CSRF_TIMEOUT_RETRY || time.Since(tok.Created) > csrf.CSRF_CLEAN_EVERY || c.Request.UserAgent() != tok.Remote {
				c.ResponseWriter.WriteHeader(http.StatusBadRequest)
				json.NewEncoder(c.ResponseWriter).Encode(map[string]any{
					"error": "CSRF not allowed",
				})
				return

			}
			csrf.Csrf_tokens.Set(tok.Value, csrf.Token{
				Value:   tok.Value,
				Used:    true,
				Retry:   tok.Retry + 1,
				Remote:  c.Request.UserAgent(),
				Created: tok.Created,
			})
		}
		handler(c)
	}
}
View Source
var GZIP = gzip.GZIP
View Source
var LOGS = logs.LOGS
View Source
var MultipartSize = 10 << 20
View Source
var Origines = []string{}
View Source
var RECOVERY = func(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		defer func() {
			err := recover()
			if err != nil {
				logger.Error(err)
				jsonBody, _ := json.Marshal(map[string]string{
					"error": "There was an internal server error",
				})
				w.Header().Set("Content-Type", "application/json")
				w.WriteHeader(http.StatusInternalServerError)
				w.Write(jsonBody)
			}
		}()
		next.ServeHTTP(w, r)
	})
}
View Source
var SESSION_ENCRYPTION = true
View Source
var Static embed.FS
View Source
var Templates embed.FS

Functions

func LoadTranslations

func LoadTranslations()

func ParamsHandleFunc added in v1.0.56

func ParamsHandleFunc(r *http.Request) (map[string]string, bool)

Types

type Context

type Context struct {
	http.ResponseWriter
	*http.Request
	Params map[string]string
	// contains filtered or unexported fields
}

Context is a wrapper of responseWriter, request, and params map

func (*Context) AddHeader added in v0.6.5

func (c *Context) AddHeader(key, value string)

AddHeader Add append a header value to key if exist

func (*Context) BodyJson added in v0.5.2

func (c *Context) BodyJson() map[string]any

BodyJson get json body from request and return map USAGE : data := c.BodyJson(r)

func (*Context) BodyText added in v0.6.5

func (c *Context) BodyText() string

func (*Context) DeleteCookie

func (c *Context) DeleteCookie(key string)

DeleteCookie delete cookie with specific key

func (*Context) DeleteFile

func (c *Context) DeleteFile(path string) error

DELETE FILE

func (*Context) Download

func (c *Context) Download(data_bytes []byte, asFilename string)

Download download data_bytes(content) asFilename(test.json,data.csv,...) to the client

func (*Context) EnableTranslations

func (c *Context) EnableTranslations()

EnableTranslations get user ip, then location country using nmap, so don't use it if u don't have it install, and then it parse csv file to find the language spoken in this country, to finaly set cookie 'lang' to 'en' or 'fr'...

func (*Context) GetCookie

func (c *Context) GetCookie(key string) (string, error)

GetCookie get cookie with specific key

func (*Context) GetUserIP

func (c *Context) GetUserIP() string

func (*Context) Html added in v0.6.0

func (c *Context) Html(template_name string, data map[string]any)

Html return template_name with data to the client

func (*Context) IsAuthenticated added in v0.7.7

func (c *Context) IsAuthenticated() bool

func (*Context) Json added in v0.6.0

func (c *Context) Json(data any)

Json return json to the client

func (*Context) JsonIndent added in v0.6.0

func (c *Context) JsonIndent(data any)

JsonIndent return json indented to the client

func (*Context) ParseMultipartForm added in v1.0.9

func (c *Context) ParseMultipartForm(size ...int64) (formData url.Values, formFiles map[string][]*multipart.FileHeader)

func (*Context) QueryParam

func (c *Context) QueryParam(name string) string

QueryParam get query param

func (*Context) Redirect added in v0.6.0

func (c *Context) Redirect(path string)

Redirect redirect the client to the specified path with a custom code

func (*Context) ServeEmbededFile

func (c *Context) ServeEmbededFile(content_type string, embed_file []byte)

ServeEmbededFile serve an embeded file from handler

func (*Context) ServeFile

func (c *Context) ServeFile(content_type, path_to_file string)

ServeFile serve a file from handler

func (*Context) SetCookie

func (c *Context) SetCookie(key, value string)

SetCookie set cookie given key and value

func (*Context) SetHeader added in v0.6.5

func (c *Context) SetHeader(key, value string)

SetHeader Set the header value to the new value, old removed

func (*Context) SetStatus added in v0.7.8

func (c *Context) SetStatus(statusCode int)

SetHeader Set the header value to the new value, old removed

func (*Context) Status added in v0.6.0

func (c *Context) Status(code int) *Context

Status set status to context, will not be writed to header

func (*Context) StreamResponse

func (c *Context) StreamResponse(response string) error

StreamResponse send SSE Streaming Response

func (*Context) Text added in v0.6.0

func (c *Context) Text(body string)

Text return text with custom code to the client

func (*Context) UploadFile

func (c *Context) UploadFile(received_filename, folder_out string, acceptedFormats ...string) (string, []byte, error)

UploadFile upload received_filename into folder_out and return url,fileByte,error

func (*Context) UploadFiles added in v0.5.0

func (c *Context) UploadFiles(received_filenames []string, folder_out string, acceptedFormats ...string) ([]string, [][]byte, error)

func (*Context) User added in v0.7.7

func (c *Context) User() (models.User, bool)

type Handler

type Handler func(c *Context)

Handler

type M added in v1.0.8

type M map[string]any

type Route

type Route struct {
	Method  string
	Pattern *regexp.Regexp
	Handler
	WsHandler
	Clients         map[string]*websocket.Conn
	AllowedOrigines []string
}

Route

type Router

type Router struct {
	Routes       map[int][]Route
	DefaultRoute Handler
	Server       *http.Server
}

Router

func BareBone added in v1.0.3

func BareBone() *Router

func New

func New() *Router

New Create New Router from env file default: '.env'

func (*Router) AddEmbededTemplates

func (router *Router) AddEmbededTemplates(template_embed embed.FS, rootDir string) error

func (*Router) AddLocalTemplates

func (router *Router) AddLocalTemplates(pathToDir string) error

func (*Router) AllowOrigines added in v1.0.51

func (router *Router) AllowOrigines(origines ...string)

func (*Router) DELETE

func (router *Router) DELETE(pattern string, handler Handler, allowed_origines ...string)

DELETE handle DELETE to a route

func (*Router) Embed

func (r *Router) Embed(staticDir *embed.FS, templateDir *embed.FS)

GetEmbeded get embeded files and make them global

func (*Router) GET

func (router *Router) GET(pattern string, handler Handler)

GET handle GET to a route

func (*Router) HEAD added in v1.0.8

func (router *Router) HEAD(pattern string, handler Handler, allowed_origines ...string)

HEAD handle HEAD to a route

func (*Router) Handle added in v1.0.57

func (router *Router) Handle(method string, pattern string, handler Handler, allowed ...string)

HandlerFunc support standard library http.HandlerFunc

func (*Router) HandlerFunc added in v1.0.9

func (router *Router) HandlerFunc(method string, pattern string, handler http.HandlerFunc, allowed ...string)

HandlerFunc support standard library http.HandlerFunc

func (*Router) LoadEnv

func (router *Router) LoadEnv(files ...string)

LoadEnv load env vars from multiple files

func (*Router) NewFuncMap

func (router *Router) NewFuncMap(funcName string, function any)

func (*Router) OPTIONS added in v1.0.8

func (router *Router) OPTIONS(pattern string, handler Handler, allowed_origines ...string)

OPTIONS handle OPTIONS to a route

func (*Router) PATCH

func (router *Router) PATCH(pattern string, handler Handler, allowed_origines ...string)

PATCH handle PATCH to a route

func (*Router) POST

func (router *Router) POST(pattern string, handler Handler, allowed_origines ...string)

POST handle POST to a route

func (*Router) PUT

func (router *Router) PUT(pattern string, handler Handler, allowed_origines ...string)

PUT handle PUT to a route

func (*Router) Run

func (router *Router) Run()

Run start the server

func (*Router) SSE

func (router *Router) SSE(pattern string, handler Handler, allowed_origines ...string)

SSE handle SSE to a route

func (*Router) ServeEmbededDir

func (router *Router) ServeEmbededDir(pathLocalDir string, embeded embed.FS, webPath string)

func (*Router) ServeHTTP

func (router *Router) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP serveHTTP by handling methods,pattern,and params

func (*Router) ServeLocalDir

func (router *Router) ServeLocalDir(dirPath, webPath string)

func (*Router) UseMiddlewares

func (router *Router) UseMiddlewares(midws ...func(http.Handler) http.Handler)

UseMiddlewares chain global middlewares applied on the router

func (*Router) WS

func (router *Router) WS(pattern string, wsHandler WsHandler, allowed_origines ...string)

WS handle WS connection on a pattern

type WsContext

type WsContext struct {
	Ws     *websocket.Conn
	Params map[string]string
	Route
}

func (*WsContext) AddClient

func (c *WsContext) AddClient(key string)

AddClient add client to clients_list

func (*WsContext) Broadcast added in v0.6.0

func (c *WsContext) Broadcast(data any) error

Broadcast send message to all clients in c.Clients

func (*WsContext) BroadcastExceptCaller

func (c *WsContext) BroadcastExceptCaller(data map[string]any) error

BroadcastExceptCaller send message to all clients in c.Clients

func (*WsContext) Json added in v0.6.0

func (c *WsContext) Json(data map[string]any) error

Json send json to the client

func (*WsContext) ReceiveJson

func (c *WsContext) ReceiveJson() (map[string]any, error)

ReceiveJson receive json from ws and disconnect when stop receiving

func (*WsContext) ReceiveText

func (c *WsContext) ReceiveText() (string, error)

ReceiveText receive text from ws and disconnect when stop receiving

func (*WsContext) RemoveRequester

func (c *WsContext) RemoveRequester(name ...string)

RemoveRequester remove the client from Clients list in context

func (*WsContext) Text added in v0.6.0

func (c *WsContext) Text(data string) error

Text send text to the client

type WsHandler

type WsHandler func(c *WsContext)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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