Installing the Enforcer
  • 18 Jan 2024
  • Dark
    Light

Installing the Enforcer

  • Dark
    Light

Article Summary

Installing the GO Enforcer

The GO Enforcer is used as a middleware inside a GO web application.
Implementation steps:

  1. Import the HUMAN package.
  2. Implement the Runtime interface.
  3. Implement the Enforcer.

Import the HUMAN package

go get github.com/perimeterx/perimeterx-go-sdk/perimeterx
GitHub Repository Access
If you do not have access the Go SDK GitHub Repository, please reach out to our Customer Support team.

Implement the Runtime interface

The implementation consist of the Runtime methods:

type Runtime interface {
    GetConfig() PxConfig
    PerformSyncRequest(*http.Request, int) (*http.Response, error)
    PerformAsyncRequest(*http.Request, int)
    Log(message string)
    GetOS() string
    GetHostName() string
}

GetConfig - Create configuration map.

  • Return HUMANConfig
  • The Configuration fields should be set according to the Configuration Options section.
  • The HUMANApplication ID / AppId and HUMANToken / Auth Token can be found in the Portal, under Applications section.
  • The HUMANCookie Encryption Key can be found in the portal, under Policies section.
  • The Policy from where the Cookie Encryption Key is taken must correspond with the Application from where the Application ID / AppId and HUMANToken / Auth Token

PerformSyncRequest - perform synchronous request.

  • Return: response *http.Response, error.
  • Arguments: request *http.Request, timeout int.

PerformAsyncRequest - perform asynchronous request.

  • Arguments: request *http.Request, timeout int.
  • It is the caller's responsibility to close the body.

Log - Logging implementation.

  • Argument: message string.

GetOS - get the Operating System name.

  • Return: name string.

GetHostName - get the host name.

  • Return: name string.

Implement the Enforcer

  • The enforcer is the main function of the module.
  • It enforces the request using the runtime instance as a context and can return a blocking response or an error.
  • In case the response is empty, the request should be forward to the origin.
  • Errors are silent.
  • In addition the enforcer handles HUMAN activities.

Example:

import (
  "github.com/perimeterx/perimeterx-go-sdk/perimeterx"
)

type Adapter func(http.Handler) http.Handler

var pxConfig perimeterx.PxConfig

func main() {
    log.Printf("Go Server is running on port %d, %s OS with an %s CPU.", port, goruntime.GOOS, goruntime.GOARCH)

    pxConfig = *NewPXConfigBuilder("App ID", "Cookie Secret", "Auth Token").
        SetMonitorMode("active_blocking").
        Build()

    http.Handle("/", middleware()(http.FileServer(http.Dir("./static"))))
    http.ListenAndServe(":3000", nil)
}

func middleware() Adapter {
    return func(h http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            responseWriter := perimeterx.NewResponseWriterWrapper(w)
            response, context, err := perimeterx.Enforce(r, &ExampleRuntime{})

            fmt.Print(context.Score)

            if err != nil {
                fmt.Print(err)
            }

            if response.Body != nil {
                responseWriter.WriteHeader(response.StatusCode)
                responseWriter.Header().Set("Content-Type", response.Header.Get("Content-Type"))
                var body, _ = ioutil.ReadAll(response.Body)
                responseWriter.Write(body)
            } else {
                h.ServeHTTP(responseWriter, r)
            }
        })
    }
}

var tr = &http.Transport{
    MaxIdleConnsPerHost:   10,
    ResponseHeaderTimeout: 60 * time.Second,
}
var client = &http.Client{Transport: tr}

type ExampleRuntime struct {
}

func (runtime *ExampleRuntime) GetConfig() perimeterx.PxConfig {
    return pxConfig
}

func (runtime *ExampleRuntime) PerformSyncRequest(req *http.Request, timeout int) (*http.Response, error) {
    client.Timeout = time.Duration(timeout) * time.Millisecond
    return client.Do(req)
}

func (runtime *ExampleRuntime) PerformAsyncRequest(req *http.Request, timeout int) {
    go runtime.PerformSyncRequest(req, timeout)
}

func (runtime *ExampleRuntime) GetOS() string {
    return goruntime.GOOS
}

func (runtime *ExampleRuntime) GetHostName() string {
    osName, _ := os.Hostname()
    return osName
}

func (runtime *ExampleRuntime) Log(message string) {
    fmt.Print(message)
}

Was this article helpful?