Skip to content
Open
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
56 changes: 34 additions & 22 deletions cmd/common/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package common

import (
"encoding/json"
"fmt"
"log"
"os"
Expand Down Expand Up @@ -30,6 +31,7 @@ const (
AccountConfigKeyPartial = "account" // app-scoped account ID key
OrganizationConfigKeyPartial = "organization" // app-scoped organization ID key
WalletConfigKeyPartial = "wallet" // app-scoped HD wallet ID key
UserInfoConfigKey = "prvd-user-info" // details of the currently auth'd user
)

var CfgFile string
Expand Down Expand Up @@ -76,6 +78,34 @@ func InitConfig() {
}
}

func StoreUserDetails(user *ident.User) error {
json, err := json.Marshal(user)
if err != nil {
log.Printf("Error storing user details; %s", err)
return err
}

viper.Set(UserInfoConfigKey, string(json))
viper.WriteConfig()

return nil
}

func GetUserDetails() (*ident.User, error) {
if viper.IsSet(UserInfoConfigKey) {
raw := viper.GetString(UserInfoConfigKey)
var user ident.User
err := json.Unmarshal([]byte(raw), &user)
if err != nil {
return nil, err
}

return &user, nil
}

return nil, fmt.Errorf("please authenticate to retrieve your user info")
Copy link
Contributor

Choose a reason for hiding this comment

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

should we prompt for authentication instead of error-ing out?

Copy link
Author

@blam23 blam23 Oct 12, 2021

Choose a reason for hiding this comment

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

Nothing else does - this should be consistent. We can change design in a new PR for all of the auth failures if desired, but this isn't the place to do that.

}

func RequireUserAccessToken() string {
token := ""
if viper.IsSet(AccessTokenConfigKey) {
Expand Down Expand Up @@ -217,29 +247,11 @@ func BuildConfigKeyWithUser(keyPartial, userID string) string {
}

func isTokenExpired(bearerToken string) bool {
token, err := jwt.Parse(bearerToken, func(_jwtToken *jwt.Token) (interface{}, error) {
// uncomment when enabling local verification
// var kid *string
// if kidhdr, ok := _jwtToken.Header["kid"].(string); ok {
// kid = &kidhdr
// }

// publicKey, _, _, _ := util.ResolveJWTKeypair(kid)
// if publicKey == nil {
// msg := "failed to resolve a valid JWT verification key"
// if kid != nil {
// msg = fmt.Sprintf("%s; invalid kid specified in header: %s", msg, *kid)
// } else {
// msg = fmt.Sprintf("%s; no default verification key configured", msg)
// }
// return nil, fmt.Errorf(msg)
// }

return nil, nil
Copy link
Author

@blam23 blam23 Sep 8, 2021

Choose a reason for hiding this comment

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

Having the interface returned here be nil causes the jwt.Parse method to always fail - if we want to parse the token without verifying we need to use ParseUnverified.

})

var jwtParser jwt.Parser
token, _, err := jwtParser.ParseUnverified(bearerToken, jwt.MapClaims{})
if err != nil {
return false
log.Printf("failed to parse JWT token on behalf of authorized user; %s", err.Error())
os.Exit(1)
}

claims := token.Claims.(jwt.MapClaims)
Expand Down
44 changes: 44 additions & 0 deletions cmd/info/info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package info

import (
"fmt"
"log"
"os"

"github.com/provideplatform/provide-cli/cmd/common"
"github.com/spf13/cobra"
)

const contractTypeRegistry = "registry"

var contract map[string]interface{}
var contracts []interface{}
var contractType string

// InfoCmd is the handler for the `info` command
var InfoCmd = &cobra.Command{
Use: "info",
Short: "Get information about the currently authorized user",
Long: "Get information about the currently authorized user",
Run: showInfo,
}

func showInfo(cmd *cobra.Command, args []string) {
// User ID, email, username, ..

user, err := common.GetUserDetails()

if err != nil {
log.Printf("Unable to get user details: %s", err)
os.Exit(1)
}

if user != nil {
fmt.Println("Current User:")
fmt.Println(" ID: ", user.ID)
fmt.Println(" Name: ", user.Name)
fmt.Println(" First Name: ", user.FirstName)
fmt.Println(" Last Name: ", user.LastName)
fmt.Println(" Email: ", user.Email)
}
}
2 changes: 2 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/provideplatform/provide-cli/cmd/common"
"github.com/provideplatform/provide-cli/cmd/connectors"
"github.com/provideplatform/provide-cli/cmd/contracts"
"github.com/provideplatform/provide-cli/cmd/info"
"github.com/provideplatform/provide-cli/cmd/networks"
"github.com/provideplatform/provide-cli/cmd/nodes"
"github.com/provideplatform/provide-cli/cmd/organizations"
Expand Down Expand Up @@ -62,6 +63,7 @@ func init() {
rootCmd.AddCommand(users.UsersCmd)
rootCmd.AddCommand(vaults.VaultsCmd)
rootCmd.AddCommand(wallets.WalletsCmd)
rootCmd.AddCommand(info.InfoCmd)

common.CacheCommands(rootCmd)
}
12 changes: 10 additions & 2 deletions cmd/users/authenticate.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/spf13/viper"
)

// authenticateCmd represents the authenticate command
// AuthenticateCmd represents the authenticate command
var AuthenticateCmd = &cobra.Command{
Use: "authenticate",
Short: "Authenticate using your credentials",
Expand All @@ -34,9 +34,17 @@ func authenticate(cmd *cobra.Command, args []string) {
common.CacheAccessRefreshToken(resp.Token)
} else if resp.Token.Token != nil {
cacheAPIToken(*resp.Token.Token)
} else {
log.Println("Failed to get token from authentication response.")
os.Exit(1)
}

log.Printf("Authentication successful")
log.Print("Authentication successful")

if resp.User != nil {
common.StoreUserDetails(resp.User)
log.Printf("User ID: %s", resp.User.ID)
}
}

func cacheAPIToken(token string) {
Expand Down