Skip to content

Commit

Permalink
Merge pull request #215 from canonical/IAM-631
Browse files Browse the repository at this point in the history
Add create-fga-model command
  • Loading branch information
nsklikas committed Jan 10, 2024
2 parents 0abcafa + c0c9365 commit 18e2ab8
Show file tree
Hide file tree
Showing 29 changed files with 334 additions and 92 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ vendor:
.PHONY: vendor

build: cmd/ui/dist
$(MAKE) -C cmd build
$(GO) build -o $(GO_BIN) ./
.PHONY: build

# plan is to use this as a probe, if folder is there target wont run and npm-build will skip
Expand All @@ -46,5 +46,5 @@ npm-build:
.PHONY: npm-build

update-openfga-model:
@printf 'package authorization\n\n// Code generated by Makefile; DO NOT EDIT.\n\nvar authModel = `%s`\n' '$(shell fga model transform --file=./internal/authorization/schema.openfga | jq -c)' > ./internal/authorization/auth_model.go
@printf 'package authorization\n\n// Code generated by Makefile; DO NOT EDIT.\n\nvar AuthModel = `%s`\n' '$(shell fga model transform --file=./internal/authorization/schema.openfga | jq -c)' > ./internal/authorization/auth_model.go
.PHONY: update-openfga-model
36 changes: 34 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ At the moment the application is sourcing the following from the environment:


## Container

To build the UI oci image, you will need [rockcraft](https://canonical-rockcraft.readthedocs-hosted.com).

To install rockcraft run:
Expand Down Expand Up @@ -93,7 +94,7 @@ CLIENT_SECRET=<client_secret>
Run the login UI's dependencies:

```console
docker-compose -f docker-compose.dev.yml up -- build --force-recreate
docker-compose -f docker-compose.dev.yml --build --force-recreate up
```

Build and run the Login UI:
Expand All @@ -106,7 +107,7 @@ export PORT=4455
export TRACING_ENABLED=false
export LOG_LEVEL=debug
export AUTHORIZATION_ENABLED=false
./cmd/app
./app serve
```

To test the authorizatoin code flow you can use the Ory Hydra CLI:
Expand All @@ -130,3 +131,34 @@ hydra perform authorization-code \
--client-secret `echo "$code_client" | yq .client_secret` \
--scope openid,profile,email,offline_access
```

## OpenFGA Model Creation

The login UI relies to [OpenFGA](https://github.com/openfga/openfga/) for authorization decisions.
After you deploy the OpenFGA server, you need to create the OpenFGA store and model:

```console
./login-ui-binary create-fga-model --fga-api-token $OPENFGA_API_TOKEN --fga-api-url $OPENFGA_API_URL --store-id $STORE_ID
```

To try it locally you can deploy OpenFGA using docker-compose:
```console
docker-compose -f docker-compose.dev.yml --build --force-recreate up
```

And run with the store:
```console
make build
./app create-fga-model --fga-api-token 42 --fga-api-url http://localhost:8080 --store-id 01GP1254CHWJC1MNGVB0WDG1T0

export KRATOS_PUBLIC_URL=http://localhost:4433
export HYDRA_ADMIN_URL=http://localhost:4445
export BASE_URL=http://localhost:4455
export OPENFGA_API_SCHEME=http
export OPENFGA_API_HOST=localhost:8080
export OPENFGA_STORE_ID=01GP1254CHWJC1MNGVB0WDG1T0
export OPENFGA_API_TOKEN=42
export OPENFGA_AUTHORIZATION_MODEL_ID=01HGG9ZQ9PP3P6QHW93QBM55KM
export AUTHORIZATION_ENABLED=false
./app serve
```
66 changes: 66 additions & 0 deletions cmd/createFgaModel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
Copyright © 2024 NAME HERE <EMAIL ADDRESS>
*/
package cmd

import (
"context"
"fmt"
"net/url"

authz "github.com/canonical/identity-platform-login-ui/internal/authorization"
logging "github.com/canonical/identity-platform-login-ui/internal/logging"
monitoring "github.com/canonical/identity-platform-login-ui/internal/monitoring"
fga "github.com/canonical/identity-platform-login-ui/internal/openfga"
tracing "github.com/canonical/identity-platform-login-ui/internal/tracing"
"github.com/spf13/cobra"
)

// createFgaModelCmd represents the createFgaModel command
var createFgaModelCmd = &cobra.Command{
Use: "create-fga-model",
Short: "Creates an openfga model",
Long: `Creates an openfga model`,
Run: func(cmd *cobra.Command, args []string) {
apiUrl, _ := cmd.Flags().GetString("fga-api-url")
apiToken, _ := cmd.Flags().GetString("fga-api-token")
storeId, _ := cmd.Flags().GetString("store-id")
createModel(apiUrl, apiToken, storeId)
},
}

func init() {
rootCmd.AddCommand(createFgaModelCmd)

createFgaModelCmd.PersistentFlags().String("fga-api-url", "", "The openfga API URL")
createFgaModelCmd.PersistentFlags().String("fga-api-token", "", "The openfga API token")
createFgaModelCmd.PersistentFlags().String("store-id", "", "The openfga store to create the model in")
createFgaModelCmd.MarkPersistentFlagRequired("api-url")
createFgaModelCmd.MarkPersistentFlagRequired("api-token")
createFgaModelCmd.MarkPersistentFlagRequired("store-id")
}

func createModel(apiUrl, apiToken, storeId string) {
logger := logging.NewNoopLogger()
tracer := tracing.NewNoopTracer()
monitor := monitoring.NewNoopMonitor("", logger)
scheme, host, err := parseURL(apiUrl)
if err != nil {
panic(err)
}
cfg := fga.NewConfig(scheme, host, storeId, apiToken, "", false, tracer, monitor, logger)
fgaClient := fga.NewClient(cfg)
modelId, err := fgaClient.WriteModel(context.Background(), []byte(authz.AuthModel))
if err != nil {
panic(err)
}
fmt.Printf("Created model: %s\n", modelId)
}

func parseURL(s string) (string, string, error) {
u, err := url.Parse(s)
if err != nil {
return "", "", err
}
return u.Scheme, u.Host, nil
}
26 changes: 26 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package cmd

import (
"os"

"github.com/spf13/cobra"
)

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "",
Short: "Identity Platform Login UI",
Long: `A login UI for the Ory stack`,
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
}

func init() {
}
30 changes: 17 additions & 13 deletions cmd/main.go → cmd/serve.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"context"
Expand All @@ -9,6 +9,8 @@ import (
"os"
"os/signal"

"github.com/spf13/cobra"

"syscall"
"time"

Expand All @@ -22,7 +24,6 @@ import (
"github.com/canonical/identity-platform-login-ui/internal/monitoring/prometheus"
fga "github.com/canonical/identity-platform-login-ui/internal/openfga"
"github.com/canonical/identity-platform-login-ui/internal/tracing"
"github.com/canonical/identity-platform-login-ui/internal/version"
"github.com/canonical/identity-platform-login-ui/pkg/web"
)

Expand All @@ -33,24 +34,27 @@ import (
//go:embed ui/dist/_next/static/*/*.css
var jsFS embed.FS

func main() {
var serveCmd = &cobra.Command{
Use: "serve",
Short: "serve starts the web server",
Long: `Launch the web application, list of environment variables is available in the readme`,
Run: func(cmd *cobra.Command, args []string) {
serve()
},
}

func init() {
rootCmd.AddCommand(serveCmd)
}

func serve() {

specs := new(config.EnvSpec)

if err := envconfig.Process("", specs); err != nil {
panic(fmt.Errorf("issues with environment sourcing: %s", err))
}

flags := config.NewFlags()

switch {
case flags.ShowVersion:
fmt.Printf("App Version: %s\n", version.Version)
os.Exit(0)
default:
break
}

logger := logging.NewLogger(specs.LogLevel, specs.LogFile)

logger.Debugf("env vars: %v", specs)
Expand Down
22 changes: 22 additions & 0 deletions cmd/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package cmd

import (
"fmt"

"github.com/canonical/identity-platform-login-ui/internal/version"
"github.com/spf13/cobra"
)

// versionCmd represents the version command
var versionCmd = &cobra.Command{
Use: "version",
Short: "Get the application's version",
Long: `Get the application's version`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("App Version: %s\n", version.Version)
},
}

func init() {
rootCmd.AddCommand(versionCmd)
}
15 changes: 9 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ require (
github.com/stretchr/testify v1.8.4
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0
go.opentelemetry.io/contrib/propagators/jaeger v1.20.0
go.opentelemetry.io/otel v1.19.0
go.opentelemetry.io/otel v1.21.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.19.0
go.opentelemetry.io/otel/sdk v1.19.0
go.opentelemetry.io/otel/trace v1.19.0
go.opentelemetry.io/otel/sdk v1.21.0
go.opentelemetry.io/otel/trace v1.21.0
go.uber.org/mock v0.3.0
go.uber.org/zap v1.26.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
Expand All @@ -31,22 +31,25 @@ require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.11.1 // indirect
go.opentelemetry.io/otel/metric v1.19.0 // indirect
github.com/spf13/cobra v1.8.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
go.opentelemetry.io/otel/metric v1.21.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
go.uber.org/multierr v1.10.0 // indirect
golang.org/x/net v0.14.0 // indirect
golang.org/x/oauth2 v0.11.0 // indirect
golang.org/x/sync v0.4.0 // indirect
golang.org/x/sys v0.12.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/text v0.12.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect
Expand Down
20 changes: 20 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqy
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
Expand All @@ -15,6 +16,8 @@ github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vz
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
Expand All @@ -29,6 +32,8 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww=
github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
Expand Down Expand Up @@ -57,6 +62,11 @@ github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwa
github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg=
Expand All @@ -65,6 +75,8 @@ go.opentelemetry.io/contrib/propagators/jaeger v1.20.0 h1:iVhNKkMIpzyZqxk8jkDU2n
go.opentelemetry.io/contrib/propagators/jaeger v1.20.0/go.mod h1:cpSABr0cm/AH/HhbJjn+AudBVUMgZWdfN3Gb+ZqxSZc=
go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs=
go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 h1:3d+S281UTjM+AbF31XSOYn1qXn3BgIdWl8HNEpx08Jk=
Expand All @@ -75,10 +87,16 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.19.0 h1:Nw7Dv4lwvGrI68+
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.19.0/go.mod h1:1MsF6Y7gTqosgoZvHlzcaaM8DIMNZgJh87ykokoNH7Y=
go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE=
go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8=
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=
go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A=
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg=
go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
Expand All @@ -101,6 +119,8 @@ golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
Expand Down
2 changes: 1 addition & 1 deletion internal/authorization/auth_model.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 18e2ab8

Please sign in to comment.