The Go SDK supports the two latest Go releases and uses only the standard library. Module: github.com/teramoby/speedle-sdk/go v0.1.0, package speedle. Reference: speedle-sdk/go.
The examples check the policy described in the SDKs overview.
Add the dependency
In a new module:
go mod init example.com/speedle-example
go get github.com/teramoby/speedle-sdk/go@v0.1.0Call a local Speedle
Start Speedle and create the example policy as described in the SDKs overview. Save this program as main.go:
package main
import (
"context"
"fmt"
"os"
speedle "github.com/teramoby/speedle-sdk/go"
)
func main() {
client, err := speedle.NewClient(speedle.Config{
Backend: speedle.BackendSpeedlePlus,
Endpoint: "http://localhost:6734",
Auth: speedle.NoAuth(),
ServiceName: "docs",
})
if err != nil {
fmt.Fprintln(os.Stderr, "Speedle error:", err)
os.Exit(1)
}
defer client.Close()
ctx := context.Background()
allowed, err := client.IsAllowed(ctx, speedle.User("alice"), "get", "/docs/public", nil)
if err != nil {
fmt.Fprintln(os.Stderr, "Speedle error:", err)
os.Exit(1)
}
fmt.Printf("alice get /docs/public: allowed=%t\n", allowed)
d, err := client.Check(ctx, speedle.User("alice"), "delete", "/docs/public", nil)
if err != nil {
fmt.Fprintln(os.Stderr, "Speedle error:", err)
os.Exit(1)
}
fmt.Printf("alice delete /docs/public: allowed=%t reason=%s\n", d.Allowed, d.Reason)
}Run it:
go run .Output:
alice get /docs/public: allowed=true
alice delete /docs/public: allowed=false reason=NO_APPLICABLE_POLICIESCall Speedle Cloud
Speedle Cloud is coming soon.
The program reads the service name from SPEEDLE_SERVICE and the service’s token from SPEEDLE_TOKEN. SPEEDLE_ENDPOINT overrides the default endpoint https://cloud.speedle.io. Replace main.go with:
package main
import (
"context"
"fmt"
"os"
speedle "github.com/teramoby/speedle-sdk/go"
)
func main() {
endpoint := os.Getenv("SPEEDLE_ENDPOINT")
if endpoint == "" {
endpoint = "https://cloud.speedle.io"
}
client, err := speedle.NewClient(speedle.Config{
Backend: speedle.BackendSpeedleCloud,
Endpoint: endpoint,
Auth: speedle.BearerToken(os.Getenv("SPEEDLE_TOKEN")),
ServiceName: os.Getenv("SPEEDLE_SERVICE"),
})
if err != nil {
fmt.Fprintln(os.Stderr, "Speedle error:", err)
os.Exit(1)
}
defer client.Close()
ctx := context.Background()
allowed, err := client.IsAllowed(ctx, speedle.User("alice"), "get", "/docs/public", nil)
if err != nil {
fmt.Fprintln(os.Stderr, "Speedle error:", err)
os.Exit(1)
}
fmt.Printf("alice get /docs/public: allowed=%t\n", allowed)
d, err := client.Check(ctx, speedle.User("alice"), "delete", "/docs/public", nil)
if err != nil {
fmt.Fprintln(os.Stderr, "Speedle error:", err)
os.Exit(1)
}
fmt.Printf("alice delete /docs/public: allowed=%t reason=%s\n", d.Allowed, d.Reason)
}Set the environment and run it. read -rs keeps the token out of your shell history and screen:
export SPEEDLE_SERVICE=docs
read -rs SPEEDLE_TOKEN && export SPEEDLE_TOKEN
go run .Output, when the service has the example policy:
alice get /docs/public: allowed=true
alice delete /docs/public: allowed=false reason=NO_APPLICABLE_POLICIESThe token is a server-side secret. Never ship it to browsers, mobile apps or desktop clients.
Error handling
A denied request is not an error: IsAllowed returns false, and Check returns a decision with Allowed false and the reason, as in the delete call above. With the default settings, when a call cannot return a decision, it returns a non-nil error (NewClient does the same for an invalid configuration). The examples print Speedle error: <message> to standard error and exit with status 1.