From c8eede902462130edf492660928ce9338c816479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=9A=B0=EC=B2=A0?= Date: Fri, 15 May 2026 08:37:13 +0900 Subject: [PATCH] feat: implement endpoint, token, and tls credentials storage --- core/cli/configure.go | 18 ++++++++++++++++++ core/client/grpc.go | 24 ++++++++++++++++++++++-- core/client/request.go | 13 +++++++++++++ core/config/config.go | 3 +++ 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/core/cli/configure.go b/core/cli/configure.go index a533aba..53034e2 100644 --- a/core/cli/configure.go +++ b/core/cli/configure.go @@ -102,6 +102,21 @@ func runE(cmd *cobra.Command, _ []string) error { return err } + token, err := tui.StringPrompt("enter permify token (optional)", "", config.CliConfig.Token) + if err != nil { + return err + } + + certPath, err := tui.StringPrompt("enter cert path (optional)", "", config.CliConfig.CertPath) + if err != nil { + return err + } + + certKey, err := tui.StringPrompt("enter cert key (optional)", "", config.CliConfig.CertKey) + if err != nil { + return err + } + resp, err := client.New(url) // Todo: Implement pagination @@ -124,6 +139,9 @@ func runE(cmd *cobra.Command, _ []string) error { } config.CliConfig.PermifyURL = url config.CliConfig.Tenant = tenantIds[tenant] + config.CliConfig.Token = token + config.CliConfig.CertPath = certPath + config.CliConfig.CertKey = certKey err = config.Write() if err != nil { logger.Log.Error(err) diff --git a/core/client/grpc.go b/core/client/grpc.go index 11835df..25a3706 100644 --- a/core/client/grpc.go +++ b/core/client/grpc.go @@ -2,19 +2,39 @@ package client import ( + "crypto/tls" + "fmt" + + "github.com/Permify/permify-cli/core/config" permify "github.com/Permify/permify-go/v1" "google.golang.org/grpc" + "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" ) // New initializes a new permify client func New(endpoint string) (*permify.Client, error) { + var opts []grpc.DialOption + + if config.CliConfig.CertPath != "" && config.CliConfig.CertKey != "" { + cert, err := tls.LoadX509KeyPair(config.CliConfig.CertPath, config.CliConfig.CertKey) + if err != nil { + return nil, fmt.Errorf("failed to load x509 key pair: %w", err) + } + opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{ + Certificates: []tls.Certificate{cert}, + }))) + } else if config.CliConfig.SslEnabled { + opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{}))) + } else { + opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials())) + } + client, err := permify.NewClient( permify.Config{ Endpoint: endpoint, }, - // Todo: Implement secure call with tls certificate - grpc.WithTransportCredentials(insecure.NewCredentials()), + opts..., ) return client, err } diff --git a/core/client/request.go b/core/client/request.go index a934082..b8dc584 100644 --- a/core/client/request.go +++ b/core/client/request.go @@ -8,6 +8,7 @@ import ( "net/http" "net/url" + "github.com/Permify/permify-cli/core/config" "github.com/Permify/permify-cli/core/logger" ) @@ -40,6 +41,9 @@ func Get(host, path string, query map[string]string, respModel interface{}) erro logger.Log.Error("failed to create request object") return err } + if config.CliConfig.Token != "" { + req.Header.Add("Authorization", "Bearer "+config.CliConfig.Token) + } q := req.URL.Query() for k, v := range query { q.Add(k, v) @@ -86,6 +90,9 @@ func Post(host, path string, query map[string]string, requestModel, respModel in logger.Log.Error("failed to create request") return err } + if config.CliConfig.Token != "" { + req.Header.Add("Authorization", "Bearer "+config.CliConfig.Token) + } req.Header.Add("Content-Type", "application/json") q := req.URL.Query() for k, v := range query { @@ -124,6 +131,9 @@ func Delete(host, path string, query map[string]string, respModel interface{}) e logger.Log.Error("failed to create request object") return err } + if config.CliConfig.Token != "" { + req.Header.Add("Authorization", "Bearer "+config.CliConfig.Token) + } req.Header.Add("Content-Type", "application/json") q := req.URL.Query() for k, v := range query { @@ -166,6 +176,9 @@ func Put(host, path string, query map[string]string, requestParams, respModel in logger.Log.Error("failed to create request") return err } + if config.CliConfig.Token != "" { + req.Header.Add("Authorization", "Bearer "+config.CliConfig.Token) + } req.Header.Add("Content-Type", "application/json") q := req.URL.Query() for k, v := range query { diff --git a/core/config/config.go b/core/config/config.go index c9bdebb..33fe8c8 100644 --- a/core/config/config.go +++ b/core/config/config.go @@ -27,6 +27,9 @@ type ProfileConfigs struct { type CoreConfig struct { PermifyURL string `yaml:"permify_url"` Tenant string `yaml:"tenant"` + Token string `yaml:"token"` + CertPath string `yaml:"cert_path"` + CertKey string `yaml:"cert_key"` SslEnabled bool `yaml:"-"` }