Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow using only project API keys #384

Merged
merged 5 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/test-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ jobs:
./ory tunnel http://localhost:4001 --quiet &
env:
ORY_PROJECT_API_KEY: ${{ secrets.ORY_PROJECT_API_KEY }}
ORY_PROJECT_SLUG: admiring-tu-swczqlujc0
- name: Install dependencies
working-directory: cmd/cloudx/e2e
run: |
Expand Down Expand Up @@ -63,7 +62,6 @@ jobs:
./ory proxy https://ory-network-httpbin-ijakee5waq-ez.a.run.app/anything --rewrite-host --quiet &
env:
ORY_PROJECT_API_KEY: ${{ secrets.ORY_PROJECT_API_KEY }}
ORY_PROJECT_SLUG: admiring-tu-swczqlujc0
- name: Install Node
working-directory: cmd/cloudx/e2e
run: |
Expand Down
31 changes: 0 additions & 31 deletions .github/workflows/test.yml
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, but this was just running the same test as test-e2e/test-proxy?

This file was deleted.

5 changes: 2 additions & 3 deletions cmd/cloudx/client/api_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"context"
"errors"
"fmt"
"os"

cloud "github.com/ory/client-go"
"github.com/ory/x/cmdx"
Expand Down Expand Up @@ -66,8 +65,8 @@ func (h *CommandHelper) DeleteWorkspaceAPIKey(ctx context.Context, workspaceID,
}

func (h *CommandHelper) TemporaryAPIKey(ctx context.Context, name string) (apiKey string, cleanup func() error, err error) {
if ak := os.Getenv(ProjectAPIKey); len(ak) > 0 {
return ak, noop, nil
if h.projectAPIKey != nil {
return *h.projectAPIKey, noop, nil
}

// For all other projects, except the playground, we need to authenticate.
Expand Down
190 changes: 128 additions & 62 deletions cmd/cloudx/client/command_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,16 @@ var ErrProjectNotSet = fmt.Errorf("no project was specified")

type (
CommandHelper struct {
config *Config
projectOverride *string
workspaceOverride *string
configLocation string
noConfirm bool
isQuiet bool
VerboseErrWriter io.Writer
Stdin *bufio.Reader
openBrowserHook func(string) error
projectAPIKey *string
workspaceAPIKey *string
config *Config
projectOverride, workspaceOverride,
projectAPIKey, workspaceAPIKey,
cloudConsoleAPIURL *string
projectID, workspaceID uuid.UUID
configLocation string
noConfirm, isQuiet bool
VerboseErrWriter io.Writer
Stdin *bufio.Reader
openBrowserHook func(string) error
}
helperOptionsContextKey struct{}
CommandHelperOption func(*CommandHelper)
Expand Down Expand Up @@ -147,7 +146,11 @@ func NewCobraCommandHelper(cmd *cobra.Command, opts ...CommandHelperOption) (*Co
if config := flagx.MustGetString(cmd, FlagConfig); config != "" {
defaultOpts = append(defaultOpts, WithConfigLocation(config))
}
return NewCommandHelper(cmd.Context(), append(defaultOpts, opts...)...)
h, err := NewCommandHelper(cmd.Context(), append(defaultOpts, opts...)...)
if err != nil {
return nil, cmdx.PrintOpenAPIError(cmd, err)
}
return h, nil
}

func NewCommandHelper(ctx context.Context, opts ...CommandHelperOption) (*CommandHelper, error) {
Expand Down Expand Up @@ -180,81 +183,144 @@ func NewCommandHelper(ctx context.Context, opts ...CommandHelperOption) (*Comman
return nil, err
}

getAPIKey := func(envKey string, override *string) *string {
if override != nil {
return override
if h.workspaceAPIKey == nil {
if key, ok := os.LookupEnv(WorkspaceAPIKey); ok {
h.workspaceAPIKey = &key
}
if key, ok := os.LookupEnv(envKey); ok {
return &key
}
if h.projectAPIKey == nil {
if key, ok := os.LookupEnv(ProjectAPIKey); ok {
h.projectAPIKey = &key
}
return nil
}
h.workspaceAPIKey = getAPIKey(WorkspaceAPIKey, h.workspaceAPIKey)
h.projectAPIKey = getAPIKey(ProjectAPIKey, h.projectAPIKey)

{
// determine current workspace from all possible sources
workspace := ""
if err := h.determineWorkspaceID(ctx, config); err != nil {
return nil, err
}
if err := h.determineProjectID(ctx, config); err != nil {
return nil, err
}

return h, nil
}

func (h *CommandHelper) determineWorkspaceID(ctx context.Context, config *Config) error {
if h.workspaceAPIKey != nil {
if h.workspaceOverride != nil {
workspace = *h.workspaceOverride
} else if ws, ok := os.LookupEnv(WorkspaceKey); ok {
workspace = ws
} else {
if config.SelectedWorkspace != uuid.Nil {
workspace = config.SelectedWorkspace.String()
}
return errors.New("workspace API key is set but workspace flag is also set, please remove one")
}
workspace = strings.TrimSpace(workspace)

if id, err := uuid.FromString(workspace); err == nil {
h.workspaceOverride = pointerx.Ptr(id.String())
} else if workspace != "" {
ws, err := h.findWorkspace(ctx, workspace)
ws, err := h.ListWorkspaces(ctx)
if err != nil {
return err
}
if len(ws) > 0 {
h.workspaceID, err = uuid.FromString(ws[0].Id)
if err != nil {
return nil, err
}
if ws != nil {
h.workspaceOverride = pointerx.Ptr(ws.Id)
return fmt.Errorf("unable to parse workspace ID from response: %w", err)
}
return nil
}
return errors.New("workspace API key is set but no workspaces were found")
}
Comment on lines +208 to +224
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the new stuff for workspace API keys.


workspace := ""
if h.workspaceOverride != nil {
workspace = *h.workspaceOverride
} else if ws, ok := os.LookupEnv(WorkspaceKey); ok {
workspace = ws
} else if config.SelectedWorkspace != uuid.Nil {
h.workspaceID = config.SelectedWorkspace
return nil
}
workspace = strings.TrimSpace(workspace)
if workspace == "" {
return nil
}
{
// determine current project from all possible sources
project := ""

// At this point, we have a (partial) workspace ID or name.
if id, err := uuid.FromString(workspace); err == nil {
h.workspaceID = id
return nil
}

// We need to resolve the non-UUID identifier to the workspace ID.
ws, err := h.findWorkspace(ctx, workspace)
if err != nil {
return err
}
h.workspaceID, err = uuid.FromString(ws.Id)
if err != nil {
return fmt.Errorf("unable to parse workspace ID from response: %w", err)
}
return nil
}

func (h *CommandHelper) determineProjectID(ctx context.Context, config *Config) error {
if h.projectAPIKey != nil {
if h.projectOverride != nil {
project = *h.projectOverride
} else if pj, ok := os.LookupEnv(ProjectKey); ok {
project = pj
} else if config.SelectedProject != uuid.Nil {
project = config.SelectedProject.String()
return errors.New("project API key is set but project flag is also set, please remove one")
}
project = strings.TrimSpace(project)

if id, err := uuid.FromString(project); err == nil {
h.projectOverride = pointerx.Ptr(id.String())
} else if project != "" {
pj, err := h.findProject(ctx, project, h.workspaceOverride)
if h.workspaceID != uuid.Nil {
return errors.New("project API key is set but workspace is also set, please remove one")
}
pjs, err := h.ListProjects(ctx, nil)
if err != nil {
return err
}
if len(pjs) > 0 {
h.projectID, err = uuid.FromString(pjs[0].Id)
if err != nil {
return nil, err
}
if pj != nil {
h.projectOverride = pointerx.Ptr(pj.Id)
return fmt.Errorf("unable to parse project ID from response: %w", err)
}
return nil
}
return errors.New("project API key is set but no projects were found")
}
Comment on lines +259 to 278
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the new stuff for project API keys.


return h, nil
project := ""
if h.projectOverride != nil {
project = *h.projectOverride
} else if pj, ok := os.LookupEnv(ProjectKey); ok {
project = pj
} else if config.SelectedProject != uuid.Nil {
h.projectID = config.SelectedProject
return nil
}
project = strings.TrimSpace(project)
if project == "" {
return nil
}

// At this point, we have a (partial) project ID or slug.
if id, err := uuid.FromString(project); err == nil {
h.projectID = id
return nil
}

// We need to resolve the non-UUID identifier to the project ID.
pj, err := h.findProject(ctx, project, h.workspaceOverride)
if err != nil {
return err
}
h.projectID, err = uuid.FromString(pj.Id)
if err != nil {
return fmt.Errorf("unable to parse project ID from response: %w", err)
}
return nil
}

func (h *CommandHelper) ProjectID() (string, error) {
if h.projectOverride == nil {
if h.projectID == uuid.Nil {
return "", ErrProjectNotSet
}
return *h.projectOverride, nil
return h.projectID.String(), nil
}

func (h *CommandHelper) WorkspaceID() *string {
return h.workspaceOverride
if h.workspaceID == uuid.Nil {
return nil
}
return pointerx.Ptr(h.workspaceID.String())
}

func (h *CommandHelper) UserName(ctx context.Context) string {
Expand Down
Loading
Loading