Documentation
¶
Overview ¶
Package apitool provides few middlewares helping you create your app.
Tools in this package and sub-directories are opinionated, should be good to be used in small project. But it's suggested to write your own for large project.
Index ¶
- Variables
- func CORS(h jsonapi.Handler) (ret jsonapi.Handler)
- func DefaultOTPFailHandler(r *http.Request) (err error)
- func ForceHeader(headers map[string]string) jsonapi.Middleware
- func LastModify(h jsonapi.Handler) (ret jsonapi.Handler)
- func NewCORS(opt CORSOption) jsonapi.Middleware
- func OTPCodeByForm(key string) func(*http.Request) string
- func OTPCodeByHeader(key string) func(*http.Request) string
- func ParseResponse(resp *http.Response, result interface{}) errordeprecated
- func TOTPInForm(secret [10]byte, formKey string) jsonapi.Middleware
- func TOTPInHeader(secret [10]byte, headerKey string) jsonapi.Middleware
- type CORSOption
- type Clientdeprecated
- type TOTPMiddleware
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var E403TOTP = jsonapi.E403.SetData("failed to auth with TOTP")
E403TOTP is a predefined error indicates you are failed to auth with otp
var EClient = jsonapi.Error{Code: -1}.SetData("Client error")
EClient indicates something goes wrong at client side while calling remote jsonapi
Deprecated: api client code is rewrited and placed in package callapi.
Functions ¶
func CORS ¶
CORS is a middleware simply allow any host access your api by setting "Access-Control-Allow-Origin: *"
func DefaultOTPFailHandler ¶
DefaultOTPFailHandler is the default implementation for TOTP failure handler
It just returns E403TOTP
func ForceHeader ¶
func ForceHeader(headers map[string]string) jsonapi.Middleware
ForceHeader creates a middleware to enforce response header
func LastModify ¶
LastModify handles If-Modified-Since and Last-Modified
It detects if there's "If-Modified-Since" header in request and "Last-Modified" in response. If both exist and modified time <= request, the response is discarded and 304 is replied.
It's no-op if handler returns any error.
// If browser send If-Modified-Since >= dateA, 304 is returned, "hello" otherwise.
//
// If browser send If-Modified-Since < dateA, "hello" is always replied.
func h1(r jsonapi.Request) (interface{}, error) {
r.W().Header().Set("Last-Mdified", dateA.UTC().Format(http.TimeFormat))
return "hello", nil
}
// Always return 404 to browser.
func h2(r jsonapi.Request) (interface{}, error) {
r.W().Header().Set("Last-Mdified", dateA.UTC().Format(http.TimeFormat))
return 1, jsonapi.E404
}
func NewCORS ¶
func NewCORS(opt CORSOption) jsonapi.Middleware
NewCORS creates a middleware to set CORS headers
Fields with zero value will not be set.
func OTPCodeByForm ¶
OTPCodeByForm grabs TOTP value from post form
func OTPCodeByHeader ¶
OTPCodeByHeader grabs TOTP value from custom header
func ParseResponse
deprecated
ParseResponse parses response of a jsonapi
It's caller's response to close response body.
If any io error or json decoding error occurred, an EClient.SetOrigin(the_error) returns.
Deprecated: api client code is rewrited and placed in package callapi.
func TOTPInForm ¶
func TOTPInForm(secret [10]byte, formKey string) jsonapi.Middleware
TOTPInForm is a helper function to create TOTPMiddleware
- OTP code is passed in post form specified in formKey
- secret is 10 bytes binary string, DO NOT USE PLAIN TEXT for best security.
It is identical to the following code, which is also actual implementation:
return (TOTPMiddleware{
Secret: secret,
GetCode: OTPCodeByForm(formKey),
Failed: DefaultOTPFailHandler,
}).Middleware
func TOTPInHeader ¶
func TOTPInHeader(secret [10]byte, headerKey string) jsonapi.Middleware
TOTPInHeader is a helper function to create TOTPMiddleware
- OTP code is passed in custom HTTP header specified by headerKey.
- secret is 10 bytes binary string, DO NOT USE PLAIN TEXT for best security.
It is identical to the following code, which is also actual implementation:
return (TOTPMiddleware{
Secret: secret,
GetCode: OTPCodeByHeader(headerKey),
Failed: DefaultOTPFailHandler,
}).Middleware
Types ¶
type CORSOption ¶
type CORSOption struct {
Origin string
ExposeHeaders []string
Headers []string
MaxAge uint64
Credential bool
Methods []string
}
CORSOption defines supported parameters used by NewCORS()
type Client
deprecated
type Client interface {
// Synchronized call
//
// If any io error or json decoding error occurred, an
// EClient.SetOrigin(the_error) returns.
Exec(param, result interface{}) error
// Asynchronized call, Client take response to close the channel
// result is guaranteed to be filled when error returns.
//
// If any io error or json decoding error occurred, an
// EClient.SetOrigin(the_error) returns.
Do(param, result interface{}) chan error
}
Client is a helper to simplify the process of calling jsonapi
Any error during the call process will immediately return as jsonapi.InternalError.SetOrigin(the_error)
Deprecated: api client code is rewrited and placed in package callapi.
Example ¶
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"github.com/raohwork/jsonapi"
)
// ParamGreeting represents parameters of Greeting API
type ParamGreeting struct {
Name string
Surname string
}
// RespGreeting represents returned type of Greeting API
type RespGreeting struct {
Name string
Surname string
Greeted bool
}
// greeting is handler of Greeting API
func Greeting(r jsonapi.Request) (interface{}, error) {
var p ParamGreeting
if err := r.Decode(&p); err != nil {
return nil, jsonapi.APPERR.SetData(
"parameter format error",
).SetCode("EParamFormat")
}
return RespGreeting{
Name: p.Name,
Surname: p.Surname,
Greeted: true,
}, nil
}
// RunAPIServer creates and runs an API server
func RunAPIServer() *httptest.Server {
http.Handle("/greeting", jsonapi.Handler(Greeting))
return httptest.NewServer(http.DefaultServeMux)
}
func main() {
// start the API server
server := RunAPIServer()
defer server.Close()
client := Call("POST", server.URL+"/greeting", nil)
var resp RespGreeting
err := client.Exec(ParamGreeting{Name: "John", Surname: "Doe"}, &resp)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf(
"Have we greeted to %s %s? %v",
resp.Name, resp.Surname, resp.Greeted,
)
}
Output: Have we greeted to John Doe? true
type TOTPMiddleware ¶
type TOTPMiddleware struct {
// 80bits binary secret, REQUEIRED
Secret [10]byte
// how many digits should a code be, at least 6
//
// any value less than 6 will be forced to 6
Digit int
// how to get code from request, leave nil to use default implementation,
// which loads code from X-OTP-CODE header
//
// for best security, it is not suggested to load code from URL query
GetCode func(r *http.Request) string
// which kinds of error is returned if failed to auth, leave nil to use
// default implementation, which returns 403 error
Failed func(r *http.Request) error
}
TOTPMiddleware represents a middleware to auth client with TOTP before execution
The TOTP implementation is this middleware has following restrictions:
- Accepts only two windows: current and previous one.
func (TOTPMiddleware) HOTP ¶
func (m TOTPMiddleware) HOTP(c int64) (code string)
HOTP implements RFC4226
The signature of this function is designed for use within TOTPMiddleware.
func (TOTPMiddleware) Middleware ¶
func (m TOTPMiddleware) Middleware(h jsonapi.Handler) (ret jsonapi.Handler)
Middleware is the *real* middleware part of TOTPMiddleware