Initial tinkering
This commit is contained in:
commit
6abe8d9eb8
7 changed files with 287 additions and 0 deletions
19
Makefile
Normal file
19
Makefile
Normal file
|
@ -0,0 +1,19 @@
|
|||
make: build
|
||||
|
||||
FGA_API_HOST="http://localhost:8080"
|
||||
|
||||
.PHONY: infra-up
|
||||
|
||||
infra-up:
|
||||
@docker compose -f docker-compose.yaml up -d
|
||||
|
||||
.PHONY: check
|
||||
check:
|
||||
@curl -X GET "${FGA_API_HOST}/healthz"
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
@go build
|
||||
|
||||
clean:
|
||||
@go clean
|
16
README.md
Normal file
16
README.md
Normal file
|
@ -0,0 +1,16 @@
|
|||
# What?
|
||||
|
||||
This is a simple demo repo with thinkering based on [OpenFGA](https://openfga.dev)
|
||||
|
||||
# Run
|
||||
|
||||
```
|
||||
make infra-up
|
||||
```
|
||||
|
||||
## How to generate privkey
|
||||
|
||||
```
|
||||
openssl genrsa -out private.pem 2048
|
||||
```
|
||||
|
61
docker-compose.yaml
Normal file
61
docker-compose.yaml
Normal file
|
@ -0,0 +1,61 @@
|
|||
version: '3.8'
|
||||
|
||||
networks:
|
||||
openfga:
|
||||
|
||||
services:
|
||||
db:
|
||||
image: postgres:14
|
||||
networks:
|
||||
- openfga
|
||||
environment:
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=password
|
||||
- POSTGRES_DB=openfga
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL", "pg_isready -U postgres" ]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
pause:
|
||||
image: ubuntu
|
||||
command: sleep 5
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_started
|
||||
|
||||
migrate:
|
||||
image: openfga/openfga
|
||||
depends_on:
|
||||
pause:
|
||||
condition: service_completed_successfully
|
||||
command: |
|
||||
migrate
|
||||
environment:
|
||||
- OPENFGA_DATASTORE_ENGINE=postgres
|
||||
- OPENFGA_DATASTORE_URI=postgres://postgres:password@db:5432/openfga
|
||||
networks:
|
||||
- openfga
|
||||
|
||||
openfga:
|
||||
image: openfga/openfga
|
||||
environment:
|
||||
- OPENFGA_DATASTORE_ENGINE=postgres
|
||||
- OPENFGA_DATASTORE_URI=postgres://postgres:password@db:5432/openfga
|
||||
- OPENFGA_LOG_FORMAT=json
|
||||
command: run
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_started
|
||||
migrate:
|
||||
condition: service_completed_successfully
|
||||
networks:
|
||||
- openfga
|
||||
ports:
|
||||
# Needed for the http server
|
||||
- "8080:8080"
|
||||
# Needed for the grpc server (if used)
|
||||
- "8081:8081"
|
||||
# Needed for the playground (Do not enable in prod!)
|
||||
- "3000:3000"
|
BIN
fga-demo
Executable file
BIN
fga-demo
Executable file
Binary file not shown.
22
go.mod
Normal file
22
go.mod
Normal file
|
@ -0,0 +1,22 @@
|
|||
module balhau/fga-demo
|
||||
|
||||
go 1.18
|
||||
|
||||
require github.com/openfga/go-sdk v0.1.1
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/gofiber/fiber/v2 v2.39.0 // indirect
|
||||
github.com/gofiber/jwt/v3 v3.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
|
||||
github.com/klauspost/compress v1.15.11 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||
github.com/rivo/uniseg v0.4.2 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.40.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
golang.org/x/net v0.1.0 // indirect
|
||||
golang.org/x/sys v0.1.0 // indirect
|
||||
)
|
48
go.sum
Normal file
48
go.sum
Normal file
|
@ -0,0 +1,48 @@
|
|||
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/gofiber/fiber/v2 v2.38.1/go.mod h1:t0NlbaXzuGH7I+7M4paE848fNWInZ7mfxI/Er1fTth8=
|
||||
github.com/gofiber/fiber/v2 v2.39.0 h1:uhWpYQ6EHN8J7FOPYbI2hrdBD/KNZBC5CjbuOd4QUt4=
|
||||
github.com/gofiber/fiber/v2 v2.39.0/go.mod h1:Cmuu+elPYGqlvQvdKyjtYsjGMi69PDp8a1AY2I5B2gM=
|
||||
github.com/gofiber/jwt/v3 v3.3.2 h1:B0YFqKLL9JIeWwXg/V6YEshEaKWyjqtLjjFpUlKUCzE=
|
||||
github.com/gofiber/jwt/v3 v3.3.2/go.mod h1:4uh0J+ZI1ExJdmnaldGDnSZnowCPeudTYtdV0AlgE9o=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/jarcoal/httpmock v1.2.0 h1:gSvTxxFR/MEMfsGrvRbdfpRUMBStovlSRLw0Ep1bwwc=
|
||||
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c=
|
||||
github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
||||
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/openfga/go-sdk v0.1.1 h1:eeCs73gVb+IyJP7LAJUYitmEBTos6fI5m63wM4lT/Ps=
|
||||
github.com/openfga/go-sdk v0.1.1/go.mod h1:eNcokf21FYb6Uvx08rtDri+CuXRtLbpapQ8E3+Lbo9w=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8=
|
||||
github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.40.0 h1:CRq/00MfruPGFLTQKY8b+8SfdK60TxNztjRMnH0t1Yc=
|
||||
github.com/valyala/fasthttp v1.40.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
|
||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
121
main.go
Normal file
121
main.go
Normal file
|
@ -0,0 +1,121 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
jwt_fiber "github.com/gofiber/jwt/v3"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
fga "github.com/openfga/go-sdk"
|
||||
)
|
||||
|
||||
const privKeyPEM = `
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAtezzFs7wK1WqA7lFUOqbCNXkcnHKGs/eIlHHN1MfXN6QjzBU
|
||||
1yz+d+QeRM986PYttFB041RF+9QoNJcfow26TUhwgY8UEyeh+93hYGWT/grWJn3r
|
||||
lKhZcjOBQ3M9DDsg2oEoRZI7pOwUcoj0OpJHz0dcoj4zrkfY1JPCWLFJbr1QszsX
|
||||
Yy/soga2M5jHyVNtYz/c4JAGjQMZpnA7tGbdsGFvnZDdH1t5naKX+ybAQYItwWjo
|
||||
9kBwhf1QGoaEVm0gvu9e+VaqKT+qnqMsGqYW29iKWOSerIg1lushZL8TulAPMwFs
|
||||
wzttRvEPqcQzCKYtbNfenmvZJIajA6HYq/lc7QIDAQABAoIBAE201Sxj3dAUuhb3
|
||||
FvV2EByZCAgeNH55VV+BYL9v4NCRPFv8//AdBuB87rTjj24OYP1I9HR5dZ8YQsgb
|
||||
2OaToYULMQsV6zQ3VIg5gN/k4266gDhWxr5rnjEacNc3rNbBlsneKy50RMewExfN
|
||||
CczO2J9f0uB2AyspAyPhrTynFT+YIvE8YflbLhUVVNhsSY/yoNTmd/ybNn5tTDQY
|
||||
uT1v4wVw/6QGW1FTAmbR27MN1D+ALfFKyG8xJ5ElfoVWciiy/rneo+Ty1EZF/Z32
|
||||
DFCt5/pNr9g0hPIlBnCtMOHRUmTbfnHuWiJ0ibaMr6UC+AVgiIUKxpjbQT3hDAkW
|
||||
MX9VTB0CgYEA5Az5/hGYBWkjgsk0atwK5hTyKmnxq/fIvXVReh6PT+dIeEbBkWud
|
||||
kTat4eMZMJA/gGwkxwyBNXodFWYIhWxjiGdIpS2SXiyfQRTZPi1o3VOuw4OiYGBf
|
||||
pb6kwD+dT39QcoOAU+PsQJesONbc4EETrVnPSE3+QW3YBsb2+my2KSsCgYEAzDjP
|
||||
tyqR06rgwCcHF4EDIMizCRXhIXmMKrQyueI2QbtFFzpeTei1HzE5zqia/PlPpmWQ
|
||||
t2ZadBBIhgj+XJF70GTq4v1Mphx8YaMkZlfjRree0vOLTXHmlV8IL/i2SnYTvzRg
|
||||
PPFIUGxN9ICqNMC+syBdTUsnF4GxRbartEQe1kcCgYA3skukF5vvRlxb5tQcfR1U
|
||||
UC1M2o8hluS6ENsTXj9WHoB+j5la8NOM0bPqBVLzn2dC8CaTTqSH8QkFXuQZ4fz1
|
||||
JXSCkvy6b199v5/HJcQEuhlmutF/hEoX6tXF9kNvVQLK1P8UfggHRoPTZfaP9pTd
|
||||
s5+CYzoDtNYb4aAUTVS3/QKBgF/uG9x9maylKxf3/UPULWT8AeW1qmAwGWCB7wYU
|
||||
Ncpgro6/s0bDljkFxZLG7q8AaaLPONB9uuWkNH0Jwno3OMLmdNOViqjI3sB6gwG0
|
||||
LSWt4WRUVM5XP6pQzqbCHNcTaik58C8QZBirF19QBSPsmmfIPyusrrtDB8OokDWI
|
||||
fjfHAoGAJEwPDCzGi/4UXd221GaYidif2GW8Dpo2kqZQAC42IQwxuEw3LgWMj0v4
|
||||
IQEfT6OOYgeMmM5/qJ0RSkox6uvwlUzNpcaFzXAfmu+JNxo2LFvV/dkS+BbZyZ/Z
|
||||
HfmMlyl+W5OXOHodg+R7J/UWupYnPp0TwlWKWYUCfM88KbIl2jk=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
`
|
||||
|
||||
var (
|
||||
privateKey *rsa.PrivateKey
|
||||
)
|
||||
|
||||
func createStore() {
|
||||
var api_scheme = os.Getenv("FGA_API_SCHEME")
|
||||
var api_host = os.Getenv("FGA_API_HOST")
|
||||
|
||||
fmt.Printf("Scheme: %s, Host: %s\n", api_scheme, api_host)
|
||||
|
||||
// Set fga configuration
|
||||
conf, c_err := fga.NewConfiguration(fga.Configuration{
|
||||
ApiScheme: api_scheme,
|
||||
ApiHost: api_host,
|
||||
})
|
||||
|
||||
// Check for errors
|
||||
if c_err != nil {
|
||||
log.Fatalf("Error during fga configuration creation")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// initialize client
|
||||
fga_client := fga.NewAPIClient(conf)
|
||||
|
||||
store_resp, http_resp, r_err := fga_client.OpenFgaApi.CreateStore(context.Background()).Body(
|
||||
fga.CreateStoreRequest{
|
||||
Name: fga.PtrString("StoreDemo"),
|
||||
},
|
||||
).Execute()
|
||||
|
||||
if r_err != nil {
|
||||
log.Fatalf("Error creating store")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println(store_resp)
|
||||
fmt.Println(http_resp)
|
||||
|
||||
}
|
||||
|
||||
const PRIV_KEY_SIZE = 2048
|
||||
|
||||
func readController(c *fiber.Ctx) error {
|
||||
user := c.Locals("user").(*jwt.Token)
|
||||
claims := user.Claims.(jwt.MapClaims)
|
||||
name := claims["name"].(string)
|
||||
return c.SendString(name + " read " + c.Params("document"))
|
||||
}
|
||||
|
||||
func runFiber() {
|
||||
app := fiber.New()
|
||||
rng := rand.Reader
|
||||
var err error
|
||||
privateKey, err = rsa.GenerateKey(rng, PRIV_KEY_SIZE)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("rsa.GenerateKey: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
app.Use(jwt_fiber.New(jwt_fiber.Config{
|
||||
SigningMethod: "RS256",
|
||||
SigningKey: privateKey.Public(),
|
||||
}))
|
||||
|
||||
app.Get("/read/:document", readController)
|
||||
|
||||
app.Listen(":9999")
|
||||
}
|
||||
|
||||
func main() {
|
||||
createStore()
|
||||
runFiber()
|
||||
}
|
Loading…
Reference in a new issue