-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #136 from lpabon/tokengen
Credentials token and whoami handlers
- Loading branch information
Showing
8 changed files
with
818 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
Copyright © 2020 Portworx | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
package configcli | ||
|
||
import ( | ||
"github.com/portworx/pxc/pkg/commander" | ||
"github.com/portworx/pxc/pkg/util" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// tokenCmd represents the token command | ||
var tokenCmd *cobra.Command | ||
|
||
var _ = commander.RegisterCommandVar(func() { | ||
tokenCmd = &cobra.Command{ | ||
Use: "token", | ||
Short: "Portworx token management commands", | ||
Run: func(cmd *cobra.Command, args []string) { | ||
util.Printf("Please see pxc config credentials token --help for more commands\n") | ||
}, | ||
} | ||
}) | ||
|
||
var _ = commander.RegisterCommandInit(func() { | ||
CredentialsAddCommand(tokenCmd) | ||
}) | ||
|
||
func CredentialsTokenAddCommand(cmd *cobra.Command) { | ||
tokenCmd.AddCommand(cmd) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
/* | ||
Copyright © 2020 Portworx | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
package configcli | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
"time" | ||
|
||
"github.com/portworx/pxc/pkg/auth" | ||
"github.com/portworx/pxc/pkg/commander" | ||
"github.com/portworx/pxc/pkg/config" | ||
"github.com/portworx/pxc/pkg/portworx" | ||
"github.com/portworx/pxc/pkg/util" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
type whoamiOptions struct { | ||
token string | ||
} | ||
|
||
var ( | ||
whoamiArgs *whoamiOptions | ||
whoamiCmd *cobra.Command | ||
) | ||
|
||
var _ = commander.RegisterCommandVar(func() { | ||
whoamiArgs = &whoamiOptions{} | ||
whoamiCmd = &cobra.Command{ | ||
Use: "whoami", | ||
Short: "Shows current authentication information", | ||
RunE: whoAmIExec, | ||
} | ||
}) | ||
|
||
var _ = commander.RegisterCommandInit(func() { | ||
CredentialsAddCommand(whoamiCmd) | ||
whoamiCmd.Flags().StringVar(&whoamiArgs.token, | ||
"auth-token", "", "Use this token instead of the token saved in the configuration. Useful for debugging tokens") | ||
}) | ||
|
||
func WhoAmIAddCommand(cmd *cobra.Command) { | ||
whoamiCmd.AddCommand(cmd) | ||
} | ||
|
||
func whoAmIExec(cmd *cobra.Command, args []string) error { | ||
token := whoamiArgs.token | ||
if len(token) == 0 { | ||
authInfo := config.CM().GetCurrentAuthInfo() | ||
token = authInfo.Token | ||
|
||
if len(authInfo.KubernetesAuthInfo.SecretName) != 0 && | ||
len(authInfo.KubernetesAuthInfo.SecretNamespace) != 0 { | ||
var err error | ||
token, err = portworx.PxGetTokenFromSecret(authInfo.KubernetesAuthInfo.SecretName, authInfo.KubernetesAuthInfo.SecretNamespace) | ||
if err != nil { | ||
return fmt.Errorf("Unable to retreive token from Kubernetes: %v", err) | ||
} | ||
} | ||
if len(token) == 0 { | ||
util.Printf("No authentication information provided") | ||
return nil | ||
} | ||
} | ||
|
||
expTime, err := auth.GetExpiration(token) | ||
if err != nil { | ||
return fmt.Errorf("Unable to get expiration information from token: %v", err) | ||
} | ||
iatTime, err := auth.GetIssuedAtTime(token) | ||
if err != nil { | ||
return fmt.Errorf("Unable to get issued time information from token: %v", err) | ||
} | ||
claims, err := auth.TokenClaims(token) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
status := "Ok" | ||
err = auth.ValidateToken(token) | ||
if err != nil { | ||
status = fmt.Sprintf("%v", err) | ||
} | ||
|
||
util.Printf("Name: %s\n"+ | ||
"Email: %s\n"+ | ||
"Subject: %s\n"+ | ||
"Groups: %s\n"+ | ||
"Roles: %s\n"+ | ||
"Issued At Time: %s\n"+ | ||
"Expiration Time: %s\n"+ | ||
"\n"+ | ||
"Status: %s\n", | ||
claims.Name, | ||
claims.Email, | ||
claims.Subject, | ||
strings.Join(claims.Groups, ","), | ||
strings.Join(claims.Roles, ","), | ||
iatTime.Format(time.UnixDate), | ||
expTime.Format(time.UnixDate), | ||
status) | ||
|
||
return nil | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
/* | ||
Copyright © 2020 Portworx | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
package configcli | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
"time" | ||
|
||
"github.com/portworx/pxc/pkg/auth" | ||
"github.com/portworx/pxc/pkg/commander" | ||
"github.com/portworx/pxc/pkg/util" | ||
"github.com/sirupsen/logrus" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
type tokenInfo struct { | ||
issuer string | ||
subject string | ||
name string | ||
email string | ||
roles string | ||
groups string | ||
} | ||
|
||
type tokenGenOptions struct { | ||
sharedSecret string | ||
rsaPem string | ||
ecdsaPem string | ||
duration string | ||
output string | ||
token tokenInfo | ||
} | ||
|
||
// tokenGenCmd represents the tokenGen command | ||
var ( | ||
tokenGenArgs *tokenGenOptions | ||
tokenGenCmd *cobra.Command | ||
) | ||
|
||
var _ = commander.RegisterCommandVar(func() { | ||
tokenGenArgs = &tokenGenOptions{} | ||
tokenGenCmd = &cobra.Command{ | ||
Use: "generate", | ||
Aliases: []string{"gen"}, | ||
Short: "Generate a Portworx token", | ||
RunE: tokenGenExec, | ||
} | ||
}) | ||
|
||
var _ = commander.RegisterCommandInit(func() { | ||
CredentialsTokenAddCommand(tokenGenCmd) | ||
tokenGenCmd.Flags().StringVar(&tokenGenArgs.sharedSecret, | ||
"shared-secret", "", "Shared secret to sign token") | ||
tokenGenCmd.Flags().StringVar(&tokenGenArgs.rsaPem, | ||
"rsa-private-keyfile", "", "RSA Private file to sign token") | ||
tokenGenCmd.Flags().StringVar(&tokenGenArgs.ecdsaPem, | ||
"ecdsa-private-keyfile", "", "ECDSA Private file to sign token") | ||
tokenGenCmd.Flags().StringVar(&tokenGenArgs.duration, | ||
"token-duration", "1d", "Duration of time where the token will be valid. "+ | ||
"Postfix the duration by using "+ | ||
auth.SecondDef+" for seconds, "+ | ||
auth.MinuteDef+" for minutes, "+ | ||
auth.HourDef+" for hours, "+ | ||
auth.DayDef+" for days, and "+ | ||
auth.YearDef+" for years.") | ||
tokenGenCmd.Flags().StringVar(&tokenGenArgs.token.issuer, | ||
"token-issuer", "portworx.com", | ||
"Issuer name of token. Do not use https:// in the issuer since it could indicate "+ | ||
"that this is an OpenID Connect issuer.") | ||
tokenGenCmd.Flags().StringVar(&tokenGenArgs.token.name, | ||
"token-name", "", "Account name") | ||
tokenGenCmd.Flags().StringVar(&tokenGenArgs.token.subject, | ||
"token-subject", "", "Unique ID of this account") | ||
tokenGenCmd.Flags().StringVar(&tokenGenArgs.token.email, | ||
"token-email", "", "Unique ID of this account") | ||
tokenGenCmd.Flags().StringVar(&tokenGenArgs.token.roles, | ||
"token-roles", "", "Comma separated list of roles applied to this token") | ||
tokenGenCmd.Flags().StringVar(&tokenGenArgs.token.groups, | ||
"token-groups", "", "Comma separated list of groups which the token will be part of") | ||
|
||
}) | ||
|
||
func TokenGenerateAddCommand(cmd *cobra.Command) { | ||
tokenGenCmd.AddCommand(cmd) | ||
} | ||
|
||
func tokenGenExec(cmd *cobra.Command, args []string) error { | ||
|
||
if len(tokenGenArgs.token.name) == 0 { | ||
return fmt.Errorf("Must supply an account name") | ||
} else if len(tokenGenArgs.token.email) == 0 { | ||
return fmt.Errorf("Must supply an email address") | ||
} else if len(tokenGenArgs.token.subject) == 0 { | ||
return fmt.Errorf("Must supply a unique identifier as the subject") | ||
} | ||
if len(tokenGenArgs.token.roles) == 0 { | ||
logrus.Warningf("Warning: No role provided") | ||
} | ||
if len(tokenGenArgs.token.groups) == 0 { | ||
logrus.Warningf("Warning: No role provided") | ||
} | ||
|
||
claims := &auth.Claims{ | ||
Name: tokenGenArgs.token.name, | ||
Email: tokenGenArgs.token.email, | ||
Subject: tokenGenArgs.token.subject, | ||
Roles: strings.Split(tokenGenArgs.token.roles, ","), | ||
Groups: strings.Split(tokenGenArgs.token.groups, ","), | ||
} | ||
|
||
// Get duration | ||
options := &auth.Options{ | ||
Issuer: tokenGenArgs.token.issuer, | ||
} | ||
expDuration, err := auth.ParseToDuration(tokenGenArgs.duration) | ||
if err != nil { | ||
return fmt.Errorf("Unable to parse duration") | ||
} | ||
options.Expiration = time.Now().Add(expDuration).Unix() | ||
|
||
// Get signature | ||
var signature *auth.Signature | ||
if len(tokenGenArgs.sharedSecret) != 0 { | ||
signature, err = auth.NewSignatureSharedSecret(tokenGenArgs.sharedSecret) | ||
} else if len(tokenGenArgs.rsaPem) != 0 { | ||
signature, err = auth.NewSignatureRSAFromFile(tokenGenArgs.rsaPem) | ||
} else if len(tokenGenArgs.ecdsaPem) != 0 { | ||
signature, err = auth.NewSignatureECDSAFromFile(tokenGenArgs.ecdsaPem) | ||
} else { | ||
return fmt.Errorf("Must provide a secret key to sign token") | ||
} | ||
if err != nil { | ||
return fmt.Errorf("Unable to generate signature: %v", err) | ||
} | ||
|
||
// Generate token | ||
token, err := auth.Token(claims, signature, options) | ||
if err != nil { | ||
return fmt.Errorf("Failed to create token: %v", err) | ||
} | ||
|
||
// Print token | ||
util.Printf("%s\n", token) | ||
|
||
return nil | ||
} |
Oops, something went wrong.