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(core): move auth profiles to externalized profiles lib #468

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from
Draft
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: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ jobs:
uses: opentdf/platform/test/start-up-with-containers@main
with:
platform-ref: 'main'
- uses: opentdf/otdfctl/e2e@main
- uses: opentdf/otdfctl/e2e@feat/profiles-lib
with:
otdfctl-ref: ${{ github.event.pull_request.head.sha }}
20 changes: 9 additions & 11 deletions cmd/auth-clientCredentials.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package cmd

import (
"github.com/opentdf/otdfctl/pkg/auth"
"github.com/opentdf/otdfctl/internal/auth"
"github.com/opentdf/otdfctl/pkg/cli"
"github.com/opentdf/otdfctl/pkg/man"
"github.com/opentdf/otdfctl/pkg/profiles"
Expand All @@ -15,7 +15,7 @@ var clientCredentialsCmd = man.Docs.GetCommand("auth/client-credentials",

func auth_clientCredentials(cmd *cobra.Command, args []string) {
c := cli.New(cmd, args)
_, cp := InitProfile(c, false)
profileMgr, currProfile := InitProfile(c, false)

var clientId string
var clientSecret string
Expand All @@ -35,26 +35,24 @@ func auth_clientCredentials(cmd *cobra.Command, args []string) {
}

// Set the client credentials
err := cp.SetAuthCredentials(profiles.AuthCredentials{
AuthType: profiles.PROFILE_AUTH_TYPE_CLIENT_CREDENTIALS,
ClientId: clientId,
currProfile.SetAuthCredentials(&auth.AuthCredentials{
AuthType: auth.AUTH_TYPE_CLIENT_CREDENTIALS,
ClientID: clientId,
ClientSecret: clientSecret,
})
if err != nil {
c.ExitWithError("Failed to set client credentials", err)
}

// Validate the client credentials
c.Printf("Validating client credentials for %s... ", cp.GetEndpoint())
if err := auth.ValidateProfileAuthCredentials(cmd.Context(), cp); err != nil {
c.Printf("Validating client credentials for %s... ", currProfile.GetEndpoint())
if err := profiles.ValidateProfileAuthCredentials(cmd.Context(), currProfile); err != nil {
c.Println("failed")
c.ExitWithError("An error occurred during login. Please check your credentials and try again", err)
}
c.Println("ok")

// Save the client credentials
c.Print("Storing client ID and secret in keyring... ")
if err := cp.Save(); err != nil {

if err := profileMgr.UpdateProfile(currProfile); err != nil {
c.Println("failed")
c.ExitWithError("An error occurred while storing client credentials", err)
}
Expand Down
19 changes: 8 additions & 11 deletions cmd/auth-login.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
package cmd

import (
"github.com/opentdf/otdfctl/pkg/auth"
"github.com/opentdf/otdfctl/internal/auth"
"github.com/opentdf/otdfctl/pkg/cli"
"github.com/opentdf/otdfctl/pkg/man"
"github.com/opentdf/otdfctl/pkg/profiles"
"github.com/spf13/cobra"
)

func auth_codeLogin(cmd *cobra.Command, args []string) {
c := cli.New(cmd, args)
_, cp := InitProfile(c, false)
profileMgr, currProfile := InitProfile(c, false)

c.Print("Initiating login...")
tok, publicClientID, err := auth.LoginWithPKCE(
cmd.Context(),
cp.GetEndpoint(),
currProfile.GetEndpoint(),
c.FlagHelper.GetOptionalString("client-id"),
c.FlagHelper.GetOptionalBool("tls-no-verify"),
)
Expand All @@ -26,20 +25,18 @@ func auth_codeLogin(cmd *cobra.Command, args []string) {
c.Println("ok")

// Set the auth credentials to profile
if err := cp.SetAuthCredentials(profiles.AuthCredentials{
AuthType: profiles.PROFILE_AUTH_TYPE_ACCESS_TOKEN,
AccessToken: profiles.AuthCredentialsAccessToken{
currProfile.SetAuthCredentials(&auth.AuthCredentials{
AuthType: auth.AUTH_TYPE_ACCESS_TOKEN,
AccessToken: &auth.AuthCredentialsAccessToken{
PublicClientID: publicClientID,
AccessToken: tok.AccessToken,
Expiration: tok.Expiry.Unix(),
RefreshToken: tok.RefreshToken,
},
}); err != nil {
c.ExitWithError("failed to set auth credentials", err)
}
})

c.Print("Storing credentials to profile in keyring...")
if err := cp.Save(); err != nil {
if err := profileMgr.UpdateProfile(currProfile); err != nil {
c.Println("failed")
c.ExitWithError("An error occurred while storing authentication credentials", err)
}
Expand Down
14 changes: 7 additions & 7 deletions cmd/auth-logout.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
package cmd

import (
"github.com/opentdf/otdfctl/pkg/auth"
"github.com/opentdf/otdfctl/internal/auth"
"github.com/opentdf/otdfctl/pkg/cli"
"github.com/opentdf/otdfctl/pkg/man"
"github.com/opentdf/otdfctl/pkg/profiles"
"github.com/spf13/cobra"
)

func auth_logout(cmd *cobra.Command, args []string) {
c := cli.New(cmd, args)
_, cp := InitProfile(c, false)
profileMgr, currProfile := InitProfile(c, false)
c.Println("Initiating logout...")

// we can only revoke access tokens stored for the code login flow, not client credentials
creds := cp.GetAuthCredentials()
if creds.AuthType == profiles.PROFILE_AUTH_TYPE_ACCESS_TOKEN {
creds := currProfile.GetAuthCredentials()
if creds.AuthType == auth.AUTH_TYPE_ACCESS_TOKEN {
c.Println("Revoking access token...")
if err := auth.RevokeAccessToken(
cmd.Context(),
cp.GetEndpoint(),
currProfile.GetEndpoint(),
creds.AccessToken.PublicClientID,
creds.AccessToken.RefreshToken,
c.FlagHelper.GetOptionalBool("tls-no-verify"),
Expand All @@ -29,7 +28,8 @@ func auth_logout(cmd *cobra.Command, args []string) {
}
}

if err := cp.SetAuthCredentials(profiles.AuthCredentials{}); err != nil {
currProfile.SetAuthCredentials(nil)
if err := profileMgr.UpdateProfile(currProfile); err != nil {
c.Println("failed")
c.ExitWithError("An error occurred while logging out", err)
}
Expand Down
10 changes: 5 additions & 5 deletions cmd/auth-printAccessToken.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package cmd

import (
"github.com/opentdf/otdfctl/pkg/auth"
"github.com/opentdf/otdfctl/internal/auth"
"github.com/opentdf/otdfctl/pkg/cli"
"github.com/opentdf/otdfctl/pkg/man"
"github.com/opentdf/otdfctl/pkg/profiles"
Expand All @@ -17,14 +17,14 @@ func auth_printAccessToken(cmd *cobra.Command, args []string) {

ac := cp.GetAuthCredentials()
switch ac.AuthType {
case profiles.PROFILE_AUTH_TYPE_CLIENT_CREDENTIALS:
c.Printf("Getting access token for %s... ", ac.ClientId)
case profiles.PROFILE_AUTH_TYPE_ACCESS_TOKEN:
case auth.AUTH_TYPE_CLIENT_CREDENTIALS:
c.Printf("Getting access token for %s... ", ac.ClientID)
case auth.AUTH_TYPE_ACCESS_TOKEN:
c.Printf("Getting profile's stored access token... ")
default:
c.ExitWithError("Invalid auth type", nil)
}
tok, err := auth.GetTokenWithProfile(cmd.Context(), cp)
tok, err := profiles.GetTokenWithProfile(cmd.Context(), cp)
if err != nil {
c.Println("failed")
cli.ExitWithError("Failed to get token", err)
Expand Down
70 changes: 43 additions & 27 deletions cmd/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"runtime"

"github.com/opentdf/otdfctl/internal/auth"
"github.com/opentdf/otdfctl/pkg/cli"
"github.com/opentdf/otdfctl/pkg/config"
"github.com/opentdf/otdfctl/pkg/profiles"
Expand All @@ -16,9 +17,10 @@ var (
)

var profileCmd = &cobra.Command{
Use: "profile",
Short: "Manage profiles (experimental)",
Hidden: runningInLinux && !runningInTestMode,
Use: "profile",
Aliases: []string{"p", "profiles"},
Short: "Manage profiles (experimental)",
Hidden: runningInLinux && !runningInTestMode,
}

var profileCreateCmd = &cobra.Command{
Expand All @@ -29,7 +31,7 @@ var profileCreateCmd = &cobra.Command{
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
c := cli.New(cmd, args)
InitProfile(c, true)
profileMgr, _ := InitProfile(c, true)

profileName := args[0]
endpoint := args[1]
Expand All @@ -38,7 +40,14 @@ var profileCreateCmd = &cobra.Command{
tlsNoVerify := c.FlagHelper.GetOptionalBool("tls-no-verify")

c.Printf("Creating profile %s... ", profileName)
if err := profile.AddProfile(profileName, endpoint, tlsNoVerify, setDefault); err != nil {
profile := &profiles.ProfileCLI{
Name: profileName,
Endpoint: endpoint,
TlsNoVerify: tlsNoVerify,
// no credentials yet creating new profile pre-login
}

if err := profileMgr.AddProfile(profile, setDefault); err != nil {
c.Println("failed")
c.ExitWithError("Failed to create profile", err)
}
Expand All @@ -53,14 +62,19 @@ var profileListCmd = &cobra.Command{
Short: "List profiles",
Run: func(cmd *cobra.Command, args []string) {
c := cli.New(cmd, args)
InitProfile(c, false)
profileMgr, currProfile := InitProfile(c, false)

profiles, err := profileMgr.ListProfiles()
if err != nil {
c.ExitWithError("Failed to list profiles", err)
}

for _, p := range profile.GetGlobalConfig().ListProfiles() {
if p == profile.GetGlobalConfig().GetDefaultProfile() {
c.Printf("* %s\n", p)
for _, p := range profiles {
if p.GetName() == currProfile.GetName() {
c.Printf("* %s\n", p.GetName())
continue
}
c.Printf(" %s\n", p)
c.Printf(" %s\n", p.GetName())
}
},
}
Expand All @@ -71,31 +85,31 @@ var profileGetCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
c := cli.New(cmd, args)
InitProfile(c, false)
profileMgr, currProfile := InitProfile(c, false)

profileName := args[0]
p, err := profile.GetProfile(profileName)
p, err := profileMgr.GetProfile(profileName)
if err != nil {
c.ExitWithError("Failed to load profile", err)
}

isDefault := "false"
if p.GetProfileName() == profile.GetGlobalConfig().GetDefaultProfile() {
if p.GetName() == currProfile.GetName() {
isDefault = "true"
}

var auth string
var authType string
ac := p.GetAuthCredentials()
if ac.AuthType == profiles.PROFILE_AUTH_TYPE_CLIENT_CREDENTIALS {
if ac != nil && ac.AuthType == auth.AUTH_TYPE_CLIENT_CREDENTIALS {
maskedSecret := "********"
auth = "client-credentials (" + ac.ClientId + ", " + maskedSecret + ")"
authType = "client-credentials (" + ac.ClientID + ", " + maskedSecret + ")"
}

t := cli.NewTabular(
[]string{"Profile", p.GetProfileName()},
[]string{"Profile", p.GetName()},
[]string{"Endpoint", p.GetEndpoint()},
[]string{"Is default", isDefault},
[]string{"Auth type", auth},
[]string{"Auth type", authType},
)

c.Print(t.View())
Expand All @@ -107,14 +121,14 @@ var profileDeleteCmd = &cobra.Command{
Short: "Delete a profile",
Run: func(cmd *cobra.Command, args []string) {
c := cli.New(cmd, args)
InitProfile(c, false)
profileMgr, _ := InitProfile(c, false)

profileName := args[0]

// TODO: suggest delete-all command to delete all profiles including default

c.Printf("Deleting profile %s... ", profileName)
if err := profile.DeleteProfile(profileName); err != nil {
if err := profileMgr.DeleteProfile(profileName); err != nil {
if errors.Is(err, profiles.ErrDeletingDefaultProfile) {
c.ExitWithWarning("Profile is set as default. Please set another profile as default before deleting.")
}
Expand All @@ -132,12 +146,12 @@ var profileSetDefaultCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
c := cli.New(cmd, args)
InitProfile(c, false)
profileMgr, _ := InitProfile(c, false)

profileName := args[0]

c.Printf("Setting profile %s as default... ", profileName)
if err := profile.SetDefaultProfile(profileName); err != nil {
if err := profileMgr.SetDefaultProfile(profileName); err != nil {
c.ExitWithError("Failed to set default profile", err)
}
c.Println("ok")
Expand All @@ -151,19 +165,21 @@ var profileSetEndpointCmd = &cobra.Command{
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
c := cli.New(cmd, args)
InitProfile(c, false)
profileMgr, _ := InitProfile(c, false)

profileName := args[0]
endpoint := args[1]

p, err := profile.GetProfile(profileName)
p, err := profileMgr.GetProfile(profileName)
if err != nil {
cli.ExitWithError("Failed to load profile", err)
}

c.Printf("Setting endpoint for profile %s... ", profileName)
if err := p.SetEndpoint(endpoint); err != nil {
c.ExitWithError("Failed to set endpoint", err)
cli.ExitWithError("Failed to set endpoint", err)
}
if err := profileMgr.UpdateProfile(p); err != nil {
c.Println("failed")
c.ExitWithError("Failed to save profile", err)
}
c.Println("ok")
},
Expand Down
Loading
Loading